C ++如何访问基类的继承和重写属性的值?

时间:2017-12-05 21:18:53

标签: c++ oop inheritance

我尝试做这样的事情:

class A{
public:
    A(){number = 1;}
    int number;
};
class B : public A{
public:
    B(){number = 2;}
};

class Base {
public:
    Base() {myAttribute = new A();}
    int returnAttrNumber(){return myAttribute->number;}
    A *myAttribute;
};

class Inherited : public Base{
public:
    Inherited(){myAttribute = new B();}
    B *myAttribute;
};


int main()
{
    Inherited *i = new Inherited();
    std::cout << i->returnAttrNumber(); // outputs 1, because it gets the A not the B. I want it to output 2, to get the B object in returnAttrNumber()
}

因此,类Base拥有一个对象A. Inherited拥有一个A派生对象B.我尝试在基类上调用一个方法,但是我希望它在相应的Object的hirarchy中被抛弃,直到可能(没有static_cast或dynamic_cast )然后拿B对象,而不是A并做东西(在这种情况下返回它的号码)

有没有办法在没有很大困难的情况下从C ++中的基类进行这种向下转换? 谢谢你的回答!

2 个答案:

答案 0 :(得分:0)

这是非常糟糕的设计。快速回答是您可以通过完全限定的标识符从基类访问变量。请看以下示例:

#include <iostream>

class A
{
public:    
    A()
    : var(1) {}

protected:
    int var;
};


class B : public A
{    
public:
    B()
    : var(2) {}

    int getBVar() const
    {
        return var;
    }

    int getAVar() const
    {
        return A::var;
    }

private:
    int var;
};

int main()
{    
    B b;
    std::cout << "A: " << b.getAVar() << std::endl;
    std::cout << "B: " << b.getBVar() << std::endl;
}

其中输出以下内容:

A: 1
B: 2

关于向下转换位... Base和Inherited具有不同的变量。你不能安全地将一个安置到另一个。

答案 1 :(得分:0)

正如rioki所说,

  

Base和Inherited具有不同的变量

这是因为我在继承中将MyAttribute重新声明为B。这是错误的。我想,当我用相同的名称声明它时,它将是同一个变量,这是错误的。 因此,整个解决方案是在Inherited中取消注释这一行。工作代码:

class A{
public:
    A(){number = 1;}
    int number;
};
class B : public A{
public:
    B(){number = 2;}
};

class Base {
public:
    Base() {myAttribute = new A();}
    int returnAttrNumber(){return myAttribute->number;}
    A *myAttribute;
};

class Inherited : public Base{
public:
    Inherited(){myAttribute = new B();}
    //B *myAttribute;
};


int main()
{
    Base *i = new Inherited(); // this works, what is necessary in my case
    std::cout << i->returnAttrNumber(); // outputs 2 now
}