使用VC71编译器并获取编译器错误,我不明白。 这是示例
class A
{
public:
virtual int& myMethod() = 0;
virtual const int& myMethod()const = 0;
};
class B: public A
{
public:
// generates: error C3241: 'const int &B::myMethod(void)' : this method was not introduced by 'A'
virtual int& A::myMethod();
// error C2555: 'B::myMethod': overriding virtual function return type differs and is not covariant from 'A::myMethod'
virtual const int& A::myMethod() const;
};
当我在B中切换两个方法定义的顺序时,我看到了不同的编译器错误:
class B: public A
{
public:
// error C3241: 'const int &B::myMethod(void)' : this method was not introduced by 'A'
virtual const int& A::myMethod() const;
// error C2556: 'int &B::myMethod(void)' : overloaded function differs only by return type from 'const int &B::myMethod(void)'
// error C2373: 'B::myMethod' : redefinition; different type modifiers
virtual int& A::myMethod();
// error C2555: 'B::myMethod': overriding virtual function return type differs and is not covariant from 'A::myMethod'
};
但是,如果我省略了A::
的东西,那么我不会得到任何编译器错误:
class B: public A
{
public:
virtual int& myMethod();
virtual const int& myMethod() const;
};
那么,在我的方法名称前面A::
究竟是什么呢?为什么我会看到这些不同的编译器错误?欢迎任何解释!
答案 0 :(得分:2)
class B: public A
{
public:
virtual const int& myMethod() const;
virtual int& myMethod();
};
删除B定义中的A::
,效果很好:)
编辑:错过了问题中的内容......
::
用于表示范围。您可以使用命名空间或类来明确限定之后查找符号的位置。
与方法结合使用,意味着您需要精确调用哪些方法,例如:
struct A { int getInt(); }
struct B: public A { int getInt(); }
B b;
b.A::getInt(); // calls A::getInt, not B::getInt
对于方法声明,这完全不正常,该方法在范围内声明,并且自然属于此范围:
namespace foo
{
int bar(); // full name is foo::bar
}
struct Foo
{
static int bar(); // full name is Foo::bar
};
但是,在引用模式时它很有用:
using foo::bar;
int a = bar(); // calls foo::bar because we asked the compiler
// to import it in the current scope
或者正如我们已经看到的那样,直接调用方法:
int B::getInt() // definition outside the class
// we need to specify what we define
{
return this->A::getInt() + 1; // call A::getInt, without precising it
// we would have a stack overflow
}
希望这有帮助。
答案 1 :(得分:1)
A ::表示你正在从A调用一个函数。这是一个你想要使用A ::
的原因的例子。class A{
public:
int m_val;
};
class B{
public:
int m_val;
};
class C: public A, public B{}
现在,当我想在C中为m_val设置一个值时,我必须这样做:
C myC;
myC::A::m_val = 4;
这样编译器就不会在你正在访问的变量之间感到困惑。
答案 2 :(得分:1)
您不应该在类声明中对函数声明进行范围化。错误消息未在C ++标准中指定。因此,每个编译器显然会为这个奇怪的东西产生不同的消息。
答案 3 :(得分:1)
我假设你正在做这样的事情来处理多重继承,即:
class A
{
public:
virtual int& myMethod() = 0;
};
class A2
{
public:
virtual int& myMethod() = 0;
};
class B: public A, public A2
{
public:
virtual int& A::myMethod();
virtual int& A2::myMethod();
};
但它不会那样工作。 B
只能有一个myMethod()
。见这里:
http://www.cprogramming.com/tutorial/multiple_inheritance.html
答案 4 :(得分:0)
在我看来,您似乎已尝试将.cpp文件内容移动到.h文件中?那些范围声明在.cpp定义文件中是有意义的,但不应该在.h声明中(正如其他人已经指出的那样)。
// generates: error C3241: 'const int &B::myMethod(void)' : this method was not introduced by 'A'
virtual int& A::myMethod();
所以在这里你说你正在使用一个虚函数,它正在实现一个在别处定义的接口函数。通过将A::
置于其前面,您说您的函数正在覆盖A
中定义的myMethod。如果您有两个基类(B
和C
为参数),它们都具有相同名称的函数,您可以使用virtual B::ThatFunction()
来覆盖B的imlpementation或virtual C::ThatFunction()
覆盖C的实现。
删除A类中的所有A::
将解决编译问题。