首页 > 解决方案 > C++ 继承:我必须在派生类中重复父属性吗?

问题描述

如果我将我的类分成头文件/实现文件,是否可以在不需要在子类中重新声明继承属性的情况下进行继承?

让我用一个例子来澄清一下。为什么允许这样做(取自此处):

#include <iostream>

using namespace std;

// Base class
class Shape {
   public:
      void setWidth(int w) {
         width = w;
      }
      void setHeight(int h) {
         height = h;
      }

   protected:
      int width;
      int height;
};

// Derived class
class Rectangle: public Shape {
   public:
      int getArea() { 
         return (width * height); 
      }
};

int main(void) {
   Rectangle Rect;

   Rect.setWidth(5);
   Rect.setHeight(7);

   // Print the area of the object.
   cout << "Total area: " << Rect.getArea() << endl;

   return 0;
}

但这不是(尝试在这里编译):

#include <string>
#include <iostream>

// HEADER FILE
class Person {   
public:
    virtual void speak() = 0;

protected:
    std::string name;
    std::string surname;
};

class Programmer : public Person {
public:
    Programmer(std::string, std::string);
};

// CPP FILE
Programmer::Programmer(std::string name, std::string surname) : 
    name(name), 
    surname(surname) 
{}

void Programmer::speak(){
    std::cout << "My name is " + name + " " + surname + " and I like to code!";
}

标签: c++oopinheritance

解决方案


我不确定什么是令人困惑的。成员初始化器列表仅允许指定基类或此类的直接成员。因此,您的第二个示例未编译。

同时,派生类可以访问它们的基类publicprotected基类的成员,所以这就是第一个示例可以的原因。

一个有趣的观察是以下代码将编译:

Programmer::Programmer(std::string name_, std::string surname_) {
    name = name_;
    surname = surname_;
}

请注意,这意味着name并将surname首先默认初始化(空字符串),然后将它们分配给Programmer构造函数中传递的值。这是效率损失,在某些情况下可能非常明显。

惯用地解决这个问题的正确方法是购买Person一个接受两个字符串参数并初始化成员的构造函数,然后从Programmer构造函数调用这个构造函数。


推荐阅读