我有以下C ++代码段:
#include <iostream>
using namespace std;
class A
{
public:
virtual ~A()
{
}
};
A::~A()
{
}
int main(int argc, char * argv [])
{
return 0;
}
为什么我会收到这些错误?:
错误:重新定义'A :: ~A()'A :: ~A()
错误:'虚拟A ::〜A()'先前在这里定义
virtual ~A()**
答案 0 :(得分:4)
只需在课堂上使用以下内容
virtual ~A();
而不是
virtual ~A()
{
}
编译器实际上正在告诉你这里的问题到底是什么。你有两个实现 - 一个在你的类中内联,另一个在它外面
A::~A()
{
}
你不能同时拥有两者。
答案 1 :(得分:2)
声明和定义之间存在差异。 C ++遵循ODR - One Definition Rule,即:您只需要定义ONCE 。
声明=你让世界知道存在的东西以及参数/返回类型是如何
定义=您为该函数/类/对象编写实际代码/
在您的代码中,您有两个定义和一个声明。这违反了ODR:
#include <iostream>
using namespace std;
class A
{
public:
virtual ~A() < - declares a virtual destructor
{ <- defines the code (nothing) for the virtual destructor
}
};
A::~A() <- defines the code AGAIN for the virtual destructor of the class A
{
}
int main(int argc, char * argv [])
{
return 0;
}
这是不允许的,因而是错误。如果定义是:
#include <iostream>
using namespace std;
class A
{
public:
virtual ~A()
{
printf("World?");
}
};
A::~A()
{
printf("Hello?");
}
编译器不知道你是否要打印“Hello?”还是“世界?”。
虚拟关键字在这里没有帮助,因为它只说:“如果一个类派生自这个并具有析构函数,则使用多态”。这是关于多态性的话题,所以我会放手。
答案 2 :(得分:1)
您正在定义析构函数两次 - 一旦在类中内联,一次在外部。你需要例如将内联定义更改为仅声明:
virtual ~A();
答案 3 :(得分:1)
这是类定义
中析构函数的定义class A
{
public:
virtual ~A()
{
}
};
这也是类定义之外的析构函数定义。
A::~A()
{
}
所以你定义了析构函数两次,编译器会报告这个错误。
您可以通过以下方式在类中定义析构函数
class A
{
public:
virtual ~A() = default;
};