【发布时间】:2021-02-08 16:04:42
【问题描述】:
有几个与此类似的问题,但没有人回答我对 C++ 中的继承不了解的问题。
我有一个简单的 Parent 和 Child 类,子类从父类继承。此处的示例只有一个与父级完全相同的子级,但整数 a 的值始终为 0。
classes.h
#ifndef CLASSES_H
#define CLASSES_H
class Parent {
private:
int a,b;
public:
Parent():a(0), b(0){};
Parent(int a, int b):a(a), b(b){};
int getA(){return this->a;}
int getB(){return this->b;}
};
class Child: public Parent {
public:
Child(){Parent();};
Child(int b){Parent(0, b);};
};
#endif
main.cpp
#include "classes.h"
#include <iostream>
using std::cout;
using std::endl;
int main(){
int a = 2;
int b = 4;
Parent parent = Parent(a, b);
Child child = Child(b);
cout << "Parent: A=" << parent.getA() << " : B=" << parent.getB() << endl;
cout << "Child: A=" << child.getA() << " : B=" << child.getB() << endl;
return 0;
}
output
Parent: A=2 : B=4
Child: A=0 : B=0
我本来希望Child: A=0 : B=4 在第二行,但事实并非如此。
查看其他问题,我知道如果我希望 Child 能够直接访问私有变量,它们需要受到保护或公开。但是我也看到了一个引用
派生类不会继承对私有数据成员的访问权限。但是,它确实继承了一个完整的父对象,其中包含该类声明的任何私有成员
我想了解的是如何“访问”这个父对象。我是否应该将它分配给构造函数中的某些内容,然后重写 getter 类以基本上重定向到父类的 getter 函数?因为这似乎违背了使用 OOP 来捕获父行为的目的。我认为(错误地)构造函数会在子构造函数中设置变量,但如果不是这种情况,那么在子构造函数内部的父构造函数中初始化的那些变量一定是正确的?
我有一个与上面类似的设置,其中一个子级对父级进行了轻微修改(对成员函数进行了一些更改),并且我能够使用受保护的成员变量来处理它,但我不确定它们是否是最佳实践。
【问题讨论】:
-
Child(int b){Parent(0, b);};不会像您认为的那样做。您可能希望像这样初始化父级Child(int b) : Parent(0, b) {}。 -
其中一个子节点是对父节点的轻微修改 如果子节点以不同的方式使用父节点的数据成员(修改它们),这可能会破坏父节点中的代码(因为它不“知道”派生的子类)。我会非常小心地使用它,并且只用于异国情调的用例。一种解决方案可能是将这些成员的修改放入可由派生类覆盖的虚拟方法中。 (因此,您可以坚持使用父类中的
private成员,这些成员公开给派生类以作为虚拟方法中的引用参数进行修改。) -
另一种选择是重新考虑您的设计:也许,您有两个具有相似但不同行为的类。这些也可以是从相同但抽象的父类派生的兄弟类。因此,父类可能定义了某种独特的接口,但实现只在派生的子类中。
-
您似乎混合了“变量”和“成员”。
main中的int a和Parent parent是变量,但Parent::a是成员。它们的相似之处在于都有类型和名称,但“它们存储在哪里”的问题有不同的答案。
标签: c++ oop inheritance