C++多层层级继承问题:result类无法访问marks类数据求助
解决C++多层继承中的成员访问问题
Hey there! Let's break down your question and code together—since you're new to C++, it's totally normal to get confused with inheritance rules.
首先,先给你吃个定心丸:你当前提供的代码其实是可以正常运行的!你的result类是public继承自marks,而marks里的s1、s2、s3是protected成员。在C++中,protected成员允许派生类(也就是result)的成员函数直接访问,所以你的process()方法里直接用s1 + s2 + s3是完全合法的,不会有访问权限问题。
那你为什么会觉得访问失败呢?大概率是你之前的代码存在以下某个误区:
- 你之前用了
private继承而非public继承:如果是private继承,marks的protected成员会变成result的private成员,但即使这样,result自己的成员函数还是能访问,只是外部代码不能通过result对象访问这些成员。 - 你之前把
marks的成员设为private:基类的private成员任何派生类都不能直接访问,这时候才会触发编译错误。 - 你尝试在
result里声明一个marks对象并直接访问它的protected成员:比如写marks m; m.s1;——这是不允许的,protected成员只能在类自身或者它的派生类的成员函数里访问,派生类里的其他对象(哪怕是同基类的对象)也不能直接碰。
再给你梳理下C++继承的核心访问规则(新手必记)
- public继承:基类的
public、protected成员在派生类中保持原权限,外部代码可以通过派生类对象访问基类的public成员。 - protected继承:基类的
public、protected成员在派生类中都会变成protected。 - private继承:基类的
public、protected成员在派生类中都会变成private。 - 基类的
private成员:任何派生类都不能直接访问,只能通过基类提供的public/protected成员函数来间接访问。
给你几个新手友好的代码改进建议
为了让代码更符合C++的封装原则,也更安全,你可以做这些调整:
- 用
std::string代替字符数组(比如char nm[20]),避免缓冲区溢出,操作也更简单(不用再用strcpy这种C风格函数)。 - 尽量把所有类的成员变量设为
private,然后通过getter函数让派生类或外部访问,这样封装性更好,也能避免意外修改。 - 尽量用
if-else代替嵌套的三目运算符,可读性更高。
下面是修改后的示例代码:
#include <iostream> #include <string> using namespace std; class student { private: int rl; string nm; public: void read() { cout << "enter Roll no and Name " << endl; cin >> rl >> nm; } void display() const { cout << "Roll NO:" << rl << endl; cout << "name : " << nm << endl; } // 提供getter函数供派生类或外部访问私有成员 int getRoll() const { return rl; } const string& getName() const { return nm; } }; class marks : public student { private: // 将成员设为private,增强封装性 int s1; int s2; int s3; public: void getmarks() { cout << "enter three subject marks " << endl; cin >> s1 >> s2 >> s3; } void putmarks() const { cout << "subject 1:" << s1 << endl; cout << "subject 2 :" << s2 << endl; cout << "subject 3:" << s3 << endl; } // 给派生类提供访问接口 int getS1() const { return s1; } int getS2() const { return s2; } int getS3() const { return s3; } }; class result : public marks { private: int t; float p; string div; // 用string代替char数组 public: void process() { // 通过getter访问marks的私有成员 t = getS1() + getS2() + getS3(); p = t / 3.0f; // 用if-else替代嵌套三目,可读性更强 if (p >= 60) { div = "first"; } else if (p >= 50) { div = "second"; } else { div = "third"; } } void printresult() const { cout << "total = " << t << endl; cout << "per = " << p << "%" << endl; cout << "div = " << div << endl; } }; int main(){ result x; x.read(); x.getmarks(); x.process(); x.display(); x.putmarks(); x.printresult(); return 0; }
如果还有其他疑问,随时问哦!
内容的提问来源于stack exchange,提问作者Niteesh Kulhari
相关产品推荐
相关产品推荐

