调用重写函数并使用基类中的重载变量

时间:2017-09-27 12:47:56

标签: c++ oop inheritance override overloading

我有两个基类和派生版本,它们重载/覆盖某些部分,如:

class base
{
public:
    int X = 1;
};

class deriv : public base
{
public:
    int X = 2;
};

class A
{
public:
    base K;
    virtual void doSmth()
    {
        std::cout << "A" << std::endl;
        smthElse();
    }

    virtual void smthElse()
    {
        std::cout << K.X << std::endl;
    }
};

class B : public A
{
public:
    deriv K;
    void doSmth()
    {
        std::cout << "B" << std::endl;
        smthElse();
    }
};

应用程序看起来像这样

int main()
{
    A instanceA;
    B instanceB;

    instanceA.doSmth();
    instanceB.doSmth();

    getchar();
    return 0;
}

因此,对于AB实例,输出为X = 1。我想知道为什么会这样。 A使用base(X = 1),B使用deriv(X = 2)。 deriv重载XB重载K。这是因为函数smthElse()仅在A中定义,因此A无法知道重载变量K的存在吗?

如果是这样,函数smthElse()是否有办法使用重载变量K? 我找到了using关键字,但在using A::smthElse;中添加B并未将X的行为更改为不打印为2.我唯一可以实现的方式这是通过从smthElse()复制函数A并将其插入B。 有没有不同的方式来实现我正在寻找的东西?因为复制&#39; n将相同的函数粘贴到B只是为了使用被覆盖的变量似乎有点过分。

提前致谢!

2 个答案:

答案 0 :(得分:2)

instanceB有两个名为KA::KB::K的变量。但是,基类A只知道一个KA::K

这解释了输出。

  

如果是这样,函数smthElse()是否有办法使用重载变量K?

是的,您可以通过在virtual中添加A函数来返回对base的引用,并在base中添加一个返回引用的i class base { public: int& getX( return X;} private: int X = 1; }; class deriv : public base { public: int& getX( return X;} private: int X = 2; }; class A { public: base& getK() { return K; } virtual void doSmth() { std::cout << "A" << std::endl; smthElse(); } virtual void smthElse() { std::cout << getK().getX() << std::endl; // ^^^^^^^^^^^^^ use the virtual functions } public: base K; }; class B : public A { public: deriv& getK(){ return K; } void doSmth() { std::cout << "B" << std::endl; smthElse(); } public: base K; };

SampleArray=np.random.randint(1,100, size=(5,5))    
    [[49 72 88 56 41]
     [30 73  6 43 53]
     [83 54 65 16 34]
     [25 17 73 10 46]
     [75 77 82 12 91]]

PS 我希望这只是好奇心,你不会用这种风格编写生产代码。你最终会混淆自己和任何试图理解你的代码的人。

答案 1 :(得分:0)

写作时

virtual void smthElse()
{
    std::cout << K.X << std::endl;
}
  • smthElsevirtual
  • K不是(成员变量不能是virtual:它对属性没有意义)。

换句话说,这意味着B::smthElse会过度A::smthElse,但 B::KA::K是两个不同,无关且独立的变量。

smthElse的上下文中调用B时,K仍然意味着A::K

作为解决方案,您可以创建K的虚拟访问者:

class base { ...};
class deriv{ ...};

class A
{
    base K;
public:
    virtual const base& theK() { return K; }
    virtual void smthElse() { std::cout << theK().X << "\n"; }
};

class B : public A
{
    deriv K;
public:
    virtual const base& theK() { return K; }
};

B{}.smthElse()被调用时,它会调用B::theK(),它将返回B::Kderiv instance}。