Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.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++;多态性从基类访问派生类字段_C++_Polymorphism - Fatal编程技术网

C++ C++;多态性从基类访问派生类字段

C++ C++;多态性从基类访问派生类字段,c++,polymorphism,C++,Polymorphism,我有以下计划: #include <iostream> class Base {}; class Deriv : public Base { public: int data; Deriv(int data): data(data) {} }; int main() { Base *t = new Deriv(2); std::cout << t->data << std::endl; }

我有以下计划:

#include <iostream>

class Base {};

class Deriv : public Base
{
    public:
        int data;
        Deriv(int data): data(data) {} 
};

int main()
{
    Base *t = new Deriv(2);
    std::cout << t->data << std::endl;
}

如何访问数据字段(请注意,我不想使用Deriv*t=new Deriv(2))?您已将指针声明为
Base
类型,并且编译器是正确的,该类中没有成员
数据。为了以这种方式访问成员,您需要将指针转换回
Deriv*
。为什么要将类型指针设置为基类?这通常仅在具有多态类层次结构时有用

你可以考虑使用一个虚拟函数来返回这个成员的值,但是不知道你的类和代码试图实现什么,很难推荐一种或另一种方式。基于您的小代码示例,只需使用

Deriv *t = new Deriv(2);

相反,似乎是一个更好的选择

您已将指针声明为
Base
类型,并且编译器是正确的,该类中没有成员
数据
。为了以这种方式访问成员,您需要将指针转换回
Deriv*
。为什么要将类型指针设置为基类?这通常仅在具有多态类层次结构时有用

你可以考虑使用一个虚拟函数来返回这个成员的值,但是不知道你的类和代码试图实现什么,很难推荐一种或另一种方式。基于您的小代码示例,只需使用

Deriv *t = new Deriv(2);

相反,似乎是一个更好的选择

将其置于基类:

virtual int get_data() const=0;
然后派生类将需要实现它-所有派生类的所有数据都将通过接口:

class Base
{
    virtual int get_data() const = 0;
};

class Deriv: public Base
{
public:
    int data;
    Deriv(int data): data(data) {} 
    virtual int get_data() const
    { return data; }
};

将其放入基类:

virtual int get_data() const=0;
然后派生类将需要实现它-所有派生类的所有数据都将通过接口:

class Base
{
    virtual int get_data() const = 0;
};

class Deriv: public Base
{
public:
    int data;
    Deriv(int data): data(data) {} 
    virtual int get_data() const
    { return data; }
};

对象
t
具有指向-
Base
的类型指针,并且
Base
未定义
data
成员,这就是代码无法编译的原因。如果您确实知道
t
指向类型为
Deriv
的实际对象(就像您发布的代码一样),您可以强制转换它,以便能够调用
Deriv
成员:

Deriv* d = static_cast<Deriv*>(t);
std::cout << d->data << std::endl;

在任何情况下,根据您发布的代码,如果您只是使用它访问仅由
Deriv
定义的数据成员,那么通过将
t
声明为
Base*
,您实际上并没有获得任何收益,而
Base
对象
t
具有指向-
Base
的类型指针,并且
Base
没有定义
数据
成员,这就是代码无法编译的原因。如果您确实知道
t
指向类型为
Deriv
的实际对象(就像您发布的代码一样),您可以强制转换它,以便能够调用
Deriv
成员:

Deriv* d = static_cast<Deriv*>(t);
std::cout << d->data << std::endl;


在任何情况下,根据您发布的代码,如果您只是使用
t
作为
Base*
来访问仅由
Deriv

定义的数据成员,则必须首先将其强制转换为指定的类型。@AtoMerZ,这是唯一的方法吗?取决于您的要求。你也可以照@tp1说的做。Base无法了解数据。您必须以这样或那样的方式告诉它。您必须首先将它转换为指定的类型。@AtoMerZ,这是唯一的方法吗?取决于您的要求。你也可以照@tp1说的做。Base无法了解数据。你必须以这样或那样的方式告诉它。标准的解决方案+1.你应该提到这个也在Base中。也许Base不应该有这个功能。这怎么可能是标准的?@AtoMerZ这是标准的,因为它避免了类切换并引入了一个合适的接口。@tp1,你能解释一下吗?基本接口只需要设计成所有派生类都可以通过它传递数据。如果Derived2允许2个整数,那么您已经需要基类中的动态数组。标准解决方案+1.你应该提到这个也在Base中。也许Base不应该有这个功能。这怎么可能是标准的?@AtoMerZ这是标准的,因为它避免了类切换并引入了一个合适的接口。@tp1,你能解释一下吗?基本接口只需要设计成所有派生类都可以通过它传递数据。如果Derived2允许2个整数,那么基类中就已经需要动态数组了。我用一个小例子来说明我的问题。我将在需要的地方使用((Deriv*)t)->数据。@gg.kaspersky哦,我明白了,这在代码中并不明显。也许从长远来看,虚函数方法是一种可行的方法。该数据字段仅适用于Deriv类。我不想做一个虚拟的吸气剂,并强制所有继承基类的人实现它.@ G.Kaspaskok:只要你的代码工作得怎么样,那是最重要的东西,当你在C++中铸造时,你应该更喜欢使用C++风格的一个铸件,而不是普通的C风格的铸件:<代码> StasyType(t)< /C>我有一个多态类层次结构。我用一个小例子来说明我的问题。我将在需要的地方使用((Deriv*)t)->数据。@gg.kaspersky哦,我明白了,这在代码中并不明显。也许从长远来看,虚函数方法是一种可行的方法。该数据字段仅适用于Deriv类。我不想做一个虚拟的吸气剂,并强制所有继承基类的人实现它.@ G.Kaspaskok:只要你的代码工作得怎么样,那是最重要的东西,当你在C++中铸造时,你应该更喜欢使用C++风格的一个铸件,而不是普通的C风格的铸件:<代码> StasyType(t)
请注意,动态\u cast具有合理的运行时开销,有时需要设置编译时标志才能在某些编译器中正常工作