C++从基类继承的公共方法无法访问派生类中的私有成员变量
C++ public method inherited from base class can not access private member variable in derived class
我有代码:
#include <iostream>
#include <cstdlib>
using namespace std;
class Animal{
private:
int age;
public:
Animal() : age(1) {}
void toString(){
cout << "Age: " << age << endl;
}
};
class Cat : public Animal
{
public:
Cat() : age(5) {}
/*
void toString(){
cout << "Age: " << age << endl;
}*/
private:
int age;
};
int main(){
Cat tom;
tom.toString();
system("pause");
return 0;
}
但是当我运行程序时,tom 变量的年龄是 1,而不是 5。toString 无法读取年龄变量吗?如果我们在 Cat 类中打开/* */toString 方法,年龄将是 5 !
(我的英语不是很好。谢谢)
问题是Cat
在Cat
中写入age
变量,而toString()
在Animal
中读取age
变量,使用Animal
的构造函数,初始化为1
。
为了解决这个问题,你可以为Animal
提供另一个构造函数,它接受一个age
参数,用于初始化Animal
的age
成员变量。
class Animal{
private:
int age;
public:
Animal() : age(1) {}
Animal(int param_age) : age(param_age) {} // Initialize member variable age with parameter
void toString(){
cout << "Age: " << age << endl;
}
};
class Cat : public Animal
{
public:
Cat() : Animal(5) {} // Call Animal's constructor that set's the age
};
更新:另一种解决方案是在Animal
类中添加一个设置其年龄的 setter 方法。然后,您可以在 Cat
的构造函数中调用它以设置适当的年龄。
class Animal{
private:
int age;
public:
Animal() : age(1) {}
void setAge(int age) { this->age = age; }
void toString(){
cout << "Age: " << age << endl;
}
};
class Cat : public Animal
{
public:
Cat() {
setAge(5);
}
};
另一种选择是使Animal
age
成员protected
class Animal{
protected: // THIS
int age;
public:
Animal() : age(1) {}
void toString(){
cout << "Age: " << age << endl;
}
};
并删除类定义中的Cat
的age
变量。尽管这种方法很简单,但在遇到"脆基类"问题时会给您带来更大的风险。因此,我推荐前一种解决方案,因为它不太容易出现上述问题,并且恕我直言,最好坚持"针对接口而不是实现编写"原则。
问题是您在Cat
构造函数中设置Cat::age
,而不是Animal::toString
使用的Animal::age
。
将Animal::age
的可见性更改为受保护。
class Animal {
protected:
int age;
public:
Animal() : age(1) {}
void toString(){
cout << "Age: " << age << endl;
}
};
不要重新声明第二个age
(变为Cat::age
)。相反,请更改 age
的值 ( Animal::age
)。
class Cat : public Animal {
public:
Cat() {
age = 5;
}
};
尝试:
#include <iostream>
#include <cstdlib>
using namespace std;
class Animal{
private:
int age;
public:
Animal(int a = 1) // Pass in the age as a parameter.
: age(a) // Default to 1.
{}
// Prefer generic print function rather than toString()
friend std::ostream& operator<<(std::ostream& s, Animal const& a) {
return s << "Age: " << a.age << 'n'; // Prefer 'n' rather than endl
// Unless you really want to flush
// the stream (this is not usually
// the case).
}
};
class Cat : public Animal
{
public:
Cat()
: Animal(5) // Now you can call the base class constructor
{} // And get it to set 5
private:
// int age; // don't have a private copy here.
// use the one that is available in the base class.
// Prefer generic print function rather than toString()
friend std::ostream& operator<<(std::ostream& s, Cat const& a)
{
// Print Cat
// Then use the Animal priting function to print more information about the object.
return s << "A Cat: " << static_cast<Animal const&>(*a);
}
};
int main(){
Cat tom;
// tom.toString(); // Don't use a toString() method.
// overload operator<< to print to a stream.
// If you want to convert to a string the just print
// to a string stream.
std::cout << tom;
system("pause");
return 0;
}
相关文章:
- 如何使用单独文件中的派生类访问友元函数对象
- 为什么此派生对象无法访问基类的后递减方法?
- C++:为什么无法在派生类中访问受保护的构造函数?
- 如何使用 C++ 中的继承函数访问派生类中的局部变量
- 派生的 wxPanel 控件如何访问其中包含 wxDialog 中的数据?
- 从纯虚拟类 (A) 派生的指针无法访问来自纯类 (B) 的重载方法
- C ++基础私有方法在将自身转换为派生类后可以访问吗?
- 按基类对象访问派生类资源时出错
- 使(虚拟)函数在大多数派生类中无法访问中间基类中可访问,定义良好?
- 从模板化父类中的派生内部类访问受保护的成员变量
- 如何从派生类访问基类中的重载运算符?
- 两个抽象类,派生自同一个基类.如何访问从一个抽象类到另一个抽象类的指针
- C++11: 如何访问派生类中的基类成员?
- 访问派生类的 QMetaObject
- 使用基类对象访问派生的仅类方法
- 如何在 c++ 中通过基类引用访问派生类的对象?
- 派生类无法访问基类的受保护成员
- 如何在 c++ 中使用多态性访问派生类字段?
- 为了访问方法,从基类动态转换为派生类
- C++继承从基类指针访问派生类中的非虚拟函数