c++ - 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!";
}
解决方案
我不确定什么是令人困惑的。成员初始化器列表仅允许指定基类或此类的直接成员。因此,您的第二个示例未编译。
同时,派生类可以访问它们的基类public
和protected
基类的成员,所以这就是第一个示例可以的原因。
一个有趣的观察是以下代码将编译:
Programmer::Programmer(std::string name_, std::string surname_) {
name = name_;
surname = surname_;
}
请注意,这意味着name
并将surname
首先默认初始化(空字符串),然后将它们分配给Programmer
构造函数中传递的值。这是效率损失,在某些情况下可能非常明显。
惯用地解决这个问题的正确方法是购买Person
一个接受两个字符串参数并初始化成员的构造函数,然后从Programmer
构造函数调用这个构造函数。
推荐阅读
- c# - 是否有更改项目属性的功能?
- virtualenv - 全局运行虚拟环境?
- reactjs - 如何在 IE 中显示 React 应用程序?当它在所有其他浏览器本地主机和生产中正常工作时?
- facebook-messenger - 如何使按钮在信使聊天机器人上工作?
- python - neo4j 更改对象中的视觉设置
- javascript - IIFE 内部 for 循环错误 VM531:3 Uncaught TypeError: console.log(...)
- google-cloud-stackdriver - 如何检索 GCP Stackdriver 人类可读日志?
- wordpress - 图片上的弹出文字点击WordPress
- php - php google analytics api如何获取用户访问的帖子的日期和时间
- c - 如何制作#define函数的for循环?