C++ 为纯虚函数提供定义
我是一名Java程序员,对为纯虚拟函数提供定义这一事实感到困惑。在Java中,我习惯于将抽象方法视为我们将在基类中提供定义的方法。但以下代码完全有效:C++ 为纯虚函数提供定义,c++,virtual,C++,Virtual,我是一名Java程序员,对为纯虚拟函数提供定义这一事实感到困惑。在Java中,我习惯于将抽象方法视为我们将在基类中提供定义的方法。但以下代码完全有效: #include <iostream> struct A { virtual ~A() = 0; }; A::~A(){ std::cout << "~A()" << std::endl; } struct B : A { ~B(){ std::cout << "~B()" &l
#include <iostream>
struct A
{
virtual ~A() = 0;
};
A::~A(){ std::cout << "~A()" << std::endl; }
struct B : A
{
~B(){ std::cout << "~B()" << std::endl; }
};
A *a = new B;
int main()
{
delete a;
}
#包括
结构A
{
虚~A()=0;
};
A::~A(){std::cout您可以定义任何纯虚拟成员函数。但是,即使您定义了A::foo
,它仍然是纯的,因此A
和B
仍然是抽象类,可能无法实例化。这将导致编译器可能发出的任何错误。您可以定义任何纯虚拟成员函数成员函数。但是,即使您定义了A::foo
,它仍然是纯函数,因此A
和B
仍然是抽象类,可能无法实例化。这将是编译器可能发出任何错误的原因。您显然对代码第二个版本中错误的原因感到困惑
在命名空间范围中为纯虚函数(任何纯虚函数)提供定义没有错。无论它是析构函数还是常规函数,编译器都不会对此抱怨
您在代码的第二个版本中提供的A::foo
的定义是完全合法的,不会引起编译器的投诉。第二个代码的唯一问题是B
没有覆盖foo
。因此B
仍然是一个抽象类。您正在尝试实例化它
在代码的第一个版本中,从A
继承的唯一纯函数B
是析构函数,而B
中提供了析构函数的非纯定义。因此,B
不再是抽象类,可以合法实例化
在代码B
的第二个版本中,继承了A
的两个纯虚拟函数-析构函数和foo
。由于没有在B
中重写foo
,B
仍然是一个抽象类,无法实例化
仅此而已。错误与在命名空间范围中为纯虚拟函数提供主体的能力无关。您显然对代码第二版本中的错误原因感到困惑
在命名空间范围中为纯虚函数(任何纯虚函数)提供定义没有错。无论它是析构函数还是常规函数,编译器都不会对此抱怨
您在代码的第二个版本中提供的A::foo
的定义是完全合法的,不会引起编译器的投诉。第二个代码的唯一问题是B
没有覆盖foo
。因此B
仍然是一个抽象类。您正在尝试实例化它
在代码的第一个版本中,从A
继承的唯一纯函数B
是析构函数,而B
中提供了析构函数的非纯定义。因此,B
不再是抽象类,可以合法实例化
在代码B
的第二个版本中,继承了A
的两个纯虚拟函数-析构函数和foo
。由于没有在B
中重写foo
,B
仍然是一个抽象类,无法实例化
仅此而已。错误与在命名空间范围中为纯虚拟函数提供主体的能力无关。当我使用g++4.8.2编译上述程序时,我收到以下消息:
编译器命令:
错误消息:
socc.cc:17:12:错误:无法分配抽象类型“B”的对象
A*A=新的B;
^
socc.cc:12:8:注意:因为以下虚拟函数在“B”中是纯函数:
结构B:A
^
socc.cc:9:6:note:virtualvoid A::foo()
void A::foo(){}
^
make:**[socc]错误1
错误消息的要点是,B
是一个抽象类型,因为它不提供重写的void foo();
,该函数在基类中声明为纯虚函数
A::foo()
的定义并不非法。以下程序运行正常:
#include <iostream>
struct A
{
virtual ~A() = 0;
virtual void foo() = 0;
};
void A::foo(){ }
A::~A(){ std::cout << "~A()" << std::endl; }
struct B : A
{
~B(){ std::cout << "~B()" << std::endl; }
void foo() {} // Need this to be able to instantiate B.
};
A *a = new B;
int main()
{
delete a;
}
#包括
结构A
{
虚~A()=0;
虚拟void foo()=0;
};
void A::foo(){}
A::~A(){std::cout当我使用g++4.8.2编译上述程序时,我得到以下消息:
编译器命令:
错误消息:
socc.cc:17:12:错误:无法分配抽象类型“B”的对象
A*A=新的B;
^
socc.cc:12:8:注意:因为以下虚拟函数在“B”中是纯函数:
结构B:A
^
socc.cc:9:6:note:virtualvoid A::foo()
void A::foo(){}
^
make:**[socc]错误1
错误消息的要点是,B
是一个抽象类型,因为它不提供重写的void foo();
,该函数在基类中声明为纯虚函数
A::foo()
的定义并不非法。以下程序运行正常:
#include <iostream>
struct A
{
virtual ~A() = 0;
virtual void foo() = 0;
};
void A::foo(){ }
A::~A(){ std::cout << "~A()" << std::endl; }
struct B : A
{
~B(){ std::cout << "~B()" << std::endl; }
void foo() {} // Need this to be able to instantiate B.
};
A *a = new B;
int main()
{
delete a;
}
#包括
结构A
{
虚~A()=0;
虚拟void foo()=0;
};
void A::foo(){}
A::~A(){std::cout What?为纯虚函数提供定义是完全合法的。编译器永远不会对此抱怨。第二个代码的唯一问题是您试图实例化抽象类B
,而不是为纯函数提供定义。@AnT但我在命名空间范围内这样做了。我提供了定义好了,怎么了?在哪里?我在任何地方都看不到B::foo
的定义。a::foo#include <iostream>
struct A
{
virtual ~A() = 0;
virtual void foo() = 0;
};
void A::foo(){ }
A::~A(){ std::cout << "~A()" << std::endl; }
struct B : A
{
~B(){ std::cout << "~B()" << std::endl; }
void foo() {} // Need this to be able to instantiate B.
};
A *a = new B;
int main()
{
delete a;
}