我有以下风格的代码:
class SubClass;
class SuperClass;
class SuperClass {
private:
void bar() {
SubClass().foo();
}
};
class SubClass : SuperClass {
public:
void foo() {};
};
所以基本上我有一个SuperClass,我想调用子类的方法foo()。 VS 2012给了我以下错误:
错误1错误C2514:' SubClass' :class没有构造函数。
错误2错误C2228:左边的' .foo'必须有class / struct / union。
我想做什么的正确结构是什么?
答案 0 :(得分:8)
你不能这样做。您必须(至少)在基类中声明该方法。例如:
#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()
。
答案 1 :(得分:0)
首先,您必须意识到调用SubClass().foo()
与当前对象无关 - 它将创建一个新的SubClass
对象并调用其foo
成员。如果您希望bar
函数在当前对象上调用foo
,则需要将foo
声明为基类中的虚函数,如Kiril建议的那样。
但是,如果你确实想要在一个新对象上调用foo
(这没什么意义,但无论如何),你正确地做到了。您的示例未编译,因为SubClass
是向前声明的,但未在bar
函数之前定义 - 您可能希望将bar
的实现移到SubClass
的定义之下,像这样:
class SubClass;
class SuperClass;
class SuperClass {
private:
void bar();
};
class SubClass : SuperClass {
public:
void foo() {};
};
void SuperClass::bar() {
SubClass().foo();
}
答案 2 :(得分:0)
您可以尝试使用一些CRTP, 即:
#include <iostream>
class SubClass;
template<typename T>
class SuperClass {
public:
void bar() {
((T *) this)->foo();
}
};
class SubClass : public SuperClass<SubClass> {
public:
void foo() {
std::cout << "hello crtp!" << std::endl;
};
};
int main(void){
SubClass a = SubClass();
a.bar();
return 0;
}