Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用指向基类的指针访问子类成员_C++_Oop_Class_Pointers_Inheritance - Fatal编程技术网

C++ 使用指向基类的指针访问子类成员

C++ 使用指向基类的指针访问子类成员,c++,oop,class,pointers,inheritance,C++,Oop,Class,Pointers,Inheritance,我的问题是,当我有一个指向基类(“a”)的指针指向子类(“b”)对象时,如何访问“obj”成员?我知道强制转换应该可以做到这一点,但我正在寻找更好的解决方案。您必须向下转换继承层次结构。您的案例是为使用dynamic\u cast而定制的,因为它允许您以类型安全的方式检查您试图投射的对象是否确实是预期的类型。您可以使用dynamic\u cast操作符将指向a的指针转换为指向b的指针。只有当ptr指向的对象的运行时类型为b时,转换才会成功,否则将返回空指针,因此转换后必须检查结果: class

我的问题是,当我有一个指向基类(“a”)的指针指向子类(“b”)对象时,如何访问“obj”成员?我知道强制转换应该可以做到这一点,但我正在寻找更好的解决方案。

您必须向下转换继承层次结构。您的案例是为使用
dynamic\u cast
而定制的,因为它允许您以类型安全的方式检查您试图投射的对象是否确实是预期的类型。

您可以使用
dynamic\u cast
操作符将指向
a
的指针转换为指向
b
的指针。只有当
ptr
指向的对象的运行时类型为
b
时,转换才会成功,否则将返回空指针,因此转换后必须检查结果:

class a //my base abstract class
{
public:
virtual void foo() = 0;
};

class b : public a //my child class with new member object
{
public:
void foo()
{}
int obj;
};

int main()
{
b bee;
a * ptr = &bee;
ptr->obj; //ERROR: class a has no member named "obj"
}
在GCC和Clang中(我认为在visualstudio中),您还可以使用以下语法

b* p = static_cast<b*>(ptr);
// You are assuming ptr points to an instance of b. If your assumption is
// correct, dereferencing p is safe
p->foo();
最后,如果我们想限制只读访问

if (auto x = dynamic_cast<Derived*>(x)) {
     // do something with \c x now that we know its defined     
}
if(const auto x=dynamic_cast(x)){
//现在我们已经知道它的定义,从\c x中读取一些内容
}

请注意,这很好地将
x
的范围限制在if子句内部,如果我们使用
if
else if
,一个接一个地执行多个连续的动态强制转换,这通常会更方便。

我没有考虑动态强制转换,因为它是类型安全的。一些上下文会有所帮助。你为什么要这么做?如果强制转换不是一个选项,那么在派生类中必须有一个虚拟函数重写,该重写返回指向该成员的引用或指针。然而,这通常会破坏封装。这让我们回到为什么要通过指向基类的指针访问派生类成员?@Void也许你是对的,我应该更改设计。
if (Derived* x = dynamic_cast<Derived*>(x)) {
     // do something with \c x now that we know its defined     
}
if (auto x = dynamic_cast<Derived*>(x)) {
     // do something with \c x now that we know its defined     
}
if (const auto x = dynamic_cast<Derived*>(x)) {
     // read something from \c x now that we know its defined     
}