4

我有以下风格的代码:

class SubClass;
class SuperClass;

class SuperClass {

private:

    void bar() {

        SubClass().foo();
    }
};

class SubClass : SuperClass {

public:

    void foo() {};
};

所以基本上我有一个超类,我想从那里调用子类的方法 foo() 。VS 2012 给我以下错误:

错误 1 ​​错误 C2514:“子类”:类没有构造函数。

错误 2 错误 C2228:'.foo' 的左侧必须有类/结构/联合。

我想做的正确结构是什么?

4

3 回答 3

10

你不能这样做。您必须(至少)在基类中声明该方法。例如:

#include <iostream>

class SuperClass 
{
public:
    void bar() 
    {
        foo();
    }
private:
    virtual void foo() // could be pure virtual, if you like
    {
        std::cout << "SuperClass::foo()" << std::endl;
    }
};

class SubClass : public SuperClass // do not forget to inherit public
{
public:
    virtual void foo() { std::cout << "SubClass::foo()" << std::endl; }
};

int main()
{
    SuperClass* pTest = new SubClass;

    pTest -> bar();

    delete pTest;
}

将打印SubClass::foo()

于 2013-04-01T12:04:37.010 回答
1

您可以尝试使用一些 CRTP,即:

#include <iostream>

class SubClass;

template<typename T>
class SuperClass {
private:
    void bar() {
        ((T *) this)->foo();
    }
public:
    void foobar() {
        this->bar();
    }
};

class SubClass : public SuperClass<SubClass> {
public:
    void foo() {
        std::cout << "hello crtp!" << std::endl;
    };
};

int main(void){
    SubClass a = SubClass();
    a.foobar();
    return 0;
}
于 2019-07-10T19:54:08.503 回答
0

首先,您必须意识到调用SubClass().foo()与当前对象无关——它将创建一个新SubClass对象并调用其foo成员。如果你想让bar函数调用foo当前对象,你需要foo在基类中声明为虚函数,正如 Kiril 建议的那样。

但是,如果您确实想调用foo一个新对象(这没有多大意义,但无论如何),那么您做对了。您的示例未编译,因为SubClass它是前向声明的,但未在bar函数之前定义 - 您可能希望将实现移至 的bar定义下方,如下所示SubClass: class SubClass; 类超类;

class SuperClass {

private:

    void bar();
};

class SubClass : SuperClass {

public:

    void foo() {};
};

void SuperClass::bar() {
    SubClass().foo();
}
于 2013-04-01T12:05:44.937 回答