c++ - C++ 继承类中存储的变量在哪里/
问题描述
有几个与此类似的问题,但没有人回答我对 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 来捕获父行为的目的。我认为(错误地)构造函数会在子构造函数中设置变量,但如果不是这种情况,在子构造函数内部的父构造函数中初始化的那些变量必须在某个地方对吗?
我有一个与上面类似的设置,其中一个子级对父级进行了轻微修改(对成员函数进行了一些更改),并且我能够使用受保护的成员变量来处理它,但我不确定它们是否是最好的-实践。
解决方案
问题是
孩子(int b){父母(0,b);};
该构造函数创建一个构造函数本地的父级,并在构造函数结束时超出范围。它不是新的子父级(默认构造),而是一个不同的临时父级。
Child 对象确实有父数据,只是您没有设置它。
子(int b):父(0,b){}
将 b 传递给基本构造函数以获得您期望的结果
“我想了解的是你如何“访问”这个父对象。”
如果您想直接访问 Parent 的成员数据,您可以使该数据受到保护(甚至公开!),但如果您的问题更多是关于如何让您的 getter 工作以访问该数据,那么它已经在工作,它的只是您访问的数据不是子构造函数主体中的数据集。
如果您在父构造函数上放置断点并查看会发生什么,也许这将有助于向您自己证明这一点。使用您的代码版本,您应该会看到父构造函数被调用了两次。首先,在 Childs 构造函数的主体开始之前(在这种情况下通过默认构造函数)发生构造 Child 的基 Parent 时,然后再次从 Child 构造函数的主体中调用。
如果您进行了建议的编辑,您将只会看到 Parent 构造函数被调用一次。
推荐阅读
- isabelle - Isabelle 代码生成和线性顺序
- c - 从 C 中的“自定义”toupper 语句中删除字符
- java - 如何正确编写截击回调
- twilio - 通过 API 设置自定义消息以获得帮助
- amazon-web-services - Cloudformation 宏使用跨区域 Lambda
- excel - 更改工作簿中所有工作表的过滤器所需的 VBA 代码
- groovy - 以第一个列表为键映射的 Groovy 列表列表
- time-series - 时间序列的趋势和季节性
- node.js - 在nodeJS中找不到我的用例的正则表达式
- git - 使用 git 将代码更改及时恢复到一组已知文件的特定位置