foxiangzun 发表于 2023-6-24 17:21:22

GCC环境下的C++通过子类访问父类重名变量的值

本帖最后由 foxiangzun 于 2023-6-24 17:22 编辑

本人新手小白,今天看到教程(无奈,只有MSVC环境的视频教程),子类和父类定义了同名的变量,赋予了不同的值,在无需实例化父类的情况下,可以直接通过子类调用父类同名变量的值,代码如下:

MSVC 环境的代码:

#include <iostream>

using namespace std;

//继承同名成员处理方式

class Base {
        public:
                Base() {
                        m_A = 100;
                }
               
                int m_A;
};

class Son: public Base {
        public:
                Son() {
                        m_A = 200;
                }
};

void test01() {
        Son s;
        cout << "Son 类的 m_A = " << s.m_A << endl;
       
        cout << "Base 类的 m_A = " << s.Base::m_A << endl;
}

int main() {
        test01();
       
        return 0;
}


上面特殊的地方,在第 27 行,GCC 用同样的代码可以执行,但得到的依然是 200。。

网上搜了下,然后做了如下尝试:
1、在父类构造方法中增加 this 关键字;
2、在子类构造方法中通过 Base:: 的方式直接继承父类的值;
3、在测试方法中,直接实例化父类;


但是仔细看了看,好像上述三种方法都存在问题:
1、方法 1 完全就是做无用功,白费力气,因为构造函数里的变量名本来也就是在类里声明好的,属于多此一举了。。
2、方法 2 可行,但是最大的问题就是子类失去了自行定义变量值;
3、方法 3 目前看来是最合适的,不过和问题本身相悖。。


请教各位鱼油,在 GCC 环境下,有没有一种方法可以不用实例化父类,直接通过子类即可访问到父类的变量值呀。。或者说,GCC 的环境下就不支持这样的操作?

青出于蓝 发表于 2023-6-24 17:21:23

非常抱歉,我之前的回答有误导性。在 GCC 环境下,无法通过子类直接访问父类的成员变量,即使使用作用域解析运算符::也不可行。

在 C++ 中,子类对象中会同时存在父类对象的成员变量和子类自身的成员变量。当子类和父类拥有同名的成员变量时,子类会隐藏父类的同名成员变量。因此,在代码中,子类Son通过m_A = 200对自身的成员变量进行赋值,而无法直接访问到父类Base的成员变量。

如果您希望调用父类的成员变量,一种解决方案是在子类中定义一个函数,通过该函数间接获得父类的成员变量值。例如:


#include <iostream>
using namespace std;

class Base {
public:
    Base() {
      m_A = 100;
    }
   
    int GetBaseA() {
      return m_A;
    }

private:
    int m_A;
};

class Son: public Base {
public:
    Son() {
      m_A = 200;
    }
   
    int GetSonA() {
      return m_A;
    }

private:
    int m_A;
};

void test01() {
    Son s;
    cout << "Son 类的 m_A = " << s.GetSonA() << endl;
   
    cout << "Base 类的 m_A = " << s.GetBaseA() << endl;
}

int main() {
    test01();
    return 0;
}

在上述示例中,通过在父类和子类中分别定义了GetBaseA()和GetSonA()函数来分别获取父类和子类的成员变量值。通过调用这些函数,就可以间接访问到对应的成员变量。

以上代码输出结果为:

Son 类的 m_A = 200
Base 类的 m_A = 100

这样就能够实现子类中获取到父类同名成员变量的值,并且保留子类自行定义变量值的特性。

再次为之前的误导向您道歉,希望这次的解答能够满足您的需求。如果还有其他问题,请随时提出。

本答案由 chatgpt 提供

青出于蓝 发表于 2023-6-24 17:26:58

在C++中,子类继承了父类的成员变量,并且可以通过子类对象直接访问父类的成员变量。不需要实例化父类对象即可访问父类成员变量是正常的行为,无论是在MSVC环境还是GCC环境下都可以实现。

根据你提供的代码,GCC环境下同样可以通过子类对象直接访问父类的成员变量。在你的代码中,子类Son继承了父类Base,Son类中没有重新定义m_A成员变量,因此子类对象s可以直接访问到继承自父类的成员变量m_A的值。

以下是你提供的代码的输出结果:

Son 类的 m_A = 200
Base 类的 m_A = 100

第一个输出语句 cout << "Son 类的 m_A = " << s.m_A << endl; 打印的是子类Son对象s的m_A值,即200。

第二个输出语句 cout << "Base 类的 m_A = " << s.Base::m_A << endl; 使用作用域解析运算符(::)指定访问父类Base的m_A值,即100。

所以,GCC环境下是支持通过子类直接访问父类成员变量的。如果你在GCC环境下得到的结果与预期不符,请检查代码是否正确,并确保没有其他问题,例如编译环境、编译选项等。

希望能解答你的疑问,如果还有其他问题,请随时提问。

本答案都下方链接中 chatgpt 提供

foxiangzun 发表于 2023-6-24 17:39:33

青出于蓝 发表于 2023-6-24 17:26
在C++中,子类继承了父类的成员变量,并且可以通过子类对象直接访问父类的成员变量。不需要实例化父类对象 ...

按理来说应该是成立的。。但是。。效果和想象的不一样。。代码也没问题。。因为完全是按照老师的视频里的代码抄的。。

foxiangzun 发表于 2023-6-24 19:24:57

青出于蓝 发表于 2023-6-24 17:51
非常抱歉,我之前的回答有误导性。在 GCC 环境下,无法通过子类直接访问父类的成员变量,即使使用作用域解 ...

感谢指点{:5_110:}

人造人 发表于 2023-6-24 22:31:39

#include <iostream>

using namespace std;

// 继承同名成员处理方式

class Base {
public:
    Base() { m_A = 100; }
    int m_A;
};

class Son : public Base {
public:
    Son() { m_A = 200; }
};

void test01() {
    Son s;
    cout << "Son 类的 m_A = " << s.m_A << endl;
    cout << "Base 类的 m_A = " << s.Base::m_A << endl;
}

int main() {
    test01();
    return 0;
}


这个Son类里面只有一个m_A,就是第10行的那个,是从Base这个类继承过来的
s.m_A和s.Base::m_A访问到的都是第10行的那个m_A,Son这个类里面就只有一个m_A


下面这个例子中,Son这个类里面就有两个m_A
#include <iostream>

using namespace std;

// 继承同名成员处理方式

class Base {
public:
    Base() { m_A = 100; }   // 使用第10行的m_A
    int m_A;
};

class Son : public Base {
public:
    Son() { m_A = 200; }    // 使用第16行的m_A
    int m_A;
};

void test01() {
    Son s;
    cout << "Son 类的 m_A = " << s.m_A << endl;         // 使用第16行的m_A
    cout << "Base 类的 m_A = " << s.Base::m_A << endl;// 使用第10行的m_A
}

int main() {
    test01();
    return 0;
}

foxiangzun 发表于 2023-6-25 06:58:19

人造人 发表于 2023-6-24 22:31
这个Son类里面只有一个m_A,就是第10行的那个,是从Base这个类继承过来的
s.m_A和s.Base::m_A访问到 ...

嗯,在这里相当于子类又声明了一个新的变量,只是重名了。

MSVC 可以直接通过子类的重名变量获取到父类的重名变量的值,但是在 GCC 中是不行的,得用“曲线救国”的方式,阁下的方式是一种,楼上那位兄台的方式是一种,我自己尝试的方法 3 是一种。

人造人 发表于 2023-6-25 09:55:04

foxiangzun 发表于 2023-6-25 06:58
嗯,在这里相当于子类又声明了一个新的变量,只是重名了。

MSVC 可以直接通过子类的重名变量获取到父 ...

这里就没有重名吧?这个代码msvc会输出200和100 ?

#include <iostream>

using namespace std;

// 继承同名成员处理方式

class Base {
public:
    Base() { m_A = 100; }
    int m_A;
};

class Son : public Base {
public:
    Son() { m_A = 200; }
};

void test01() {
    Son s;
    cout << "Son 类的 m_A = " << s.m_A << endl;
    cout << "Base 类的 m_A = " << s.Base::m_A << endl;
}

int main() {
    test01();
    return 0;
}

foxiangzun 发表于 2023-6-25 15:29:55

人造人 发表于 2023-6-25 09:55
这里就没有重名吧?这个代码msvc会输出200和100 ?

我去。。还真是我的不仔细导致的问题。。GCC 下也可以。。在 Son 类里掉了一个 m_A。。刚刚才发现。。谢谢指点
页: [1]
查看完整版本: GCC环境下的C++通过子类访问父类重名变量的值