C++从基类指针访问派生类成员

发布于 2024-08-24 14:02:22 字数 389 浏览 8 评论 0原文

如果我分配一个 Derived 类的对象(基类为 Base),并将指向该对象的指针存储在指向基类的变量中,如何我可以访问 Derived 类的成员吗?

这是一个例子:

class Base
{
    public:
    int base_int;
};

class Derived : public Base
{
    public:
    int derived_int;
};

Base* basepointer = new Derived();
basepointer-> //Access derived_int here, is it possible? If so, then how?

If I allocate an object of a class Derived (with a base class of Base), and store a pointer to that object in a variable that points to the base class, how can I access the members of the Derived class?

Here's an example:

class Base
{
    public:
    int base_int;
};

class Derived : public Base
{
    public:
    int derived_int;
};

Base* basepointer = new Derived();
basepointer-> //Access derived_int here, is it possible? If so, then how?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

故事与诗 2024-08-31 14:02:22

不,您无法访问 衍生_int,因为 衍生_intDerived 的一部分,而 basepointer 是指向 的指针基础

不过,您也可以反过来做:

Derived* derivedpointer = new Derived;
derivedpointer->base_int; // You can access this just fine

派生类继承基类的成员,而不是相反。

但是,如果您的 basepointer 指向 Derived 的实例,那么您可以通过强制转换来访问它:

Base* basepointer = new Derived;
static_cast<Derived*>(basepointer)->derived_int; // Can now access, because we have a derived pointer

请注意,您需要将继承更改为 public首先:

class Derived : public Base

No, you cannot access derived_int because derived_int is part of Derived, while basepointer is a pointer to Base.

You can do it the other way round though:

Derived* derivedpointer = new Derived;
derivedpointer->base_int; // You can access this just fine

Derived classes inherit the members of the base class, not the other way around.

However, if your basepointer was pointing to an instance of Derived then you could access it through a cast:

Base* basepointer = new Derived;
static_cast<Derived*>(basepointer)->derived_int; // Can now access, because we have a derived pointer

Note that you'll need to change your inheritance to public first:

class Derived : public Base
输什么也不输骨气 2024-08-31 14:02:22

你在这里的雷区跳舞。基类永远无法知道它实际上是派生类的实例。最安全的方法是在基类中引入一个虚函数:

class Base 
{ 
protected:
 virtual int &GetInt()
 {
  //Die horribly
 }

public: 
 int base_int; 
}; 

class Derived : Base 
{ 
  int &GetInt()
  {
    return derived_int;
  }
public: 
int derived_int 
}; 

basepointer->GetInt() = 0;

如果basepointer指向Derived之外的其他东西,你的程序将会可怕地死掉,这就是预期的结果。

或者,您可以使用dynamic_cast(basepointer)。但是为此,您在Base 中至少需要一个虚函数,并准备好遇到零。

就像一些人建议的那样,static_cast<>肯定是搬起石头砸自己的脚。不要为大量“C 语言家族的不安全”恐怖故事做出贡献。

You're dancing on a minefield here. The base class can never know that it's actually an instance of the derived. The safest way to do that would be to introduce a virtual function in the base:

class Base 
{ 
protected:
 virtual int &GetInt()
 {
  //Die horribly
 }

public: 
 int base_int; 
}; 

class Derived : Base 
{ 
  int &GetInt()
  {
    return derived_int;
  }
public: 
int derived_int 
}; 

basepointer->GetInt() = 0;

If basepointer points as something other that a Derived, your program will die horribly, which is the intended result.

Alternatively, you can use dynamic_cast<Derived>(basepointer). But you need at least one virtual function in the Base for that, and be prepared to encounter a zero.

The static_cast<>, like some suggest, is a sure way to shoot yourself in the foot. Don't contribute to the vast cache of "unsafety of the C language family" horror stories.

隔纱相望 2024-08-31 14:02:22

您可以使用 CRTP

您基本上在基类的模板中使用派生类

you can use CRTP

you basically use the derived class in the template for the base class

若有似无的小暗淡 2024-08-31 14:02:22

通过让基类知道派生类的类型是可能的。这可以通过使基类成为派生类型的模板来完成。这个 C++ 惯用法称为奇怪的重复模板模式

了解派生类后,可以将基类指针静态转换为指向派生类型的指针。

template<typename DerivedT>
class Base
{
public:
    int accessDerivedField()
    {
        auto derived = static_cast<DerivedT*>(this);
        return derived->field;
    }
};


class Derived : public Base<Derived>
{
public:
    int field;
};

int main()
{
    auto obj = new Derived;
    obj->accessDerivedField();
}

It is possible by letting the base class know the type of derived class. This can be done by making the base class a template of derived type. This C++ idiom is called curiously recurring template pattern.

Knowing the derived class, the base class pointer can be static-casted to a pointer to derived type.

template<typename DerivedT>
class Base
{
public:
    int accessDerivedField()
    {
        auto derived = static_cast<DerivedT*>(this);
        return derived->field;
    }
};


class Derived : public Base<Derived>
{
public:
    int field;
};

int main()
{
    auto obj = new Derived;
    obj->accessDerivedField();
}
空宴 2024-08-31 14:02:22

//如果你知道你将使用什么派生类

Derived*衍生指针=dynamic_cast<导出*>基指针;

//然后你可以使用派生指针访问派生类

//if you know what derived class you are going to use

Derived* derivedpointer = dynamic_cast < Derived * > basepointer;

//then you can access derived class using derivedpointer

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文