此 C++ 代码中的错误是什么?
What is the bug inside this C++ code?
我相信它是 C++ 但它可能是 C?自从我查看 C++ 以来已经有一段时间了,所以我最终没有找到错误。我在一次采访中被问到这个问题,但没有得到答案。我显然没有得到这份工作,但现在我很想找到答案。
#include<iostream>
class Base {
public:
Base() {
std::cerr<<"constructing Base " << this << std::endl;
i = new int;
}
~Base() {
std::cerr<<"destroying Base " << this << std::endl;
delete i;
}
private
int* i;
};
class Derived : public Base {
public:
Derived() {
std::cerr<<"constructing Dervied " << this << std::endl;
d = new double;
}
~Derived() {
std::cerr<<"destroying Derived " << this << std::endl;
delete d;
}
private
double* d;
};
int main(int argc, char** argv) {
using namespace std;
int ret = 1;
Base* thePtr = new Derived;
delete thePtr;
return ret;
}
提前致谢!
Base
的析构函数不是虚拟的。这最多会泄漏 Derived::d
指针。
实际上,在没有虚析构函数的情况下通过基class指针删除派生class的指针是未定义的行为(感谢GManNickG)
您应该将 Base
class 析构函数标记为 virtual
。在你的代码中 Base
class 析构函数不是 virtual
& 基础 class 指针指向 Derived
class 对象所以默认情况下析构函数将是称为 Base
class,除非它被标记为 virtual
。这将泄漏 Derived
class 数据成员 d
的动态分配内存并调用 未定义行为 .
让我列一个清单...
Base
析构函数不是 virtual
.
- 它使用原始指针而不是智能指针
- 事实上,它根本不需要指针,
new
和delete
- 因此,它实际上不需要析构函数。
- 也
Derived
拼写为Dervied
- ...它无法编译。
你的基础 class 析构函数应该声明为虚拟的,看起来像
cpp
virtual ~Base()
{
std::cerr<<"destroying Base " << this << std::endl;
delete i;
}
你可以在这里找到它http://www.programmerinterview.com/index.php/c-cplusplus/virtual-destructors/
当您可以通过指向基 class:
的指针删除派生 class 的实例时,虚拟析构函数很有用
there is a major problem with the code above: the destructor for the "Derive" class does not get called at all when we delete basePtr
,
派生对象的构造遵循构造规则,但是当我们删除"b"指针(基指针)时,我们发现只有基析构函数是call.But,这肯定不会发生。
为了做适当的事情,我们必须使基本析构函数成为虚拟的。它类似于运行时的多态性,因此编译器会发现这是一个基指针但指向派生的class,并自动为它绑定派生的class析构函数[=14] =]
我相信它是 C++ 但它可能是 C?自从我查看 C++ 以来已经有一段时间了,所以我最终没有找到错误。我在一次采访中被问到这个问题,但没有得到答案。我显然没有得到这份工作,但现在我很想找到答案。
#include<iostream>
class Base {
public:
Base() {
std::cerr<<"constructing Base " << this << std::endl;
i = new int;
}
~Base() {
std::cerr<<"destroying Base " << this << std::endl;
delete i;
}
private
int* i;
};
class Derived : public Base {
public:
Derived() {
std::cerr<<"constructing Dervied " << this << std::endl;
d = new double;
}
~Derived() {
std::cerr<<"destroying Derived " << this << std::endl;
delete d;
}
private
double* d;
};
int main(int argc, char** argv) {
using namespace std;
int ret = 1;
Base* thePtr = new Derived;
delete thePtr;
return ret;
}
提前致谢!
Base
的析构函数不是虚拟的。这最多会泄漏 Derived::d
指针。
实际上,在没有虚析构函数的情况下通过基class指针删除派生class的指针是未定义的行为(感谢GManNickG)
您应该将 Base
class 析构函数标记为 virtual
。在你的代码中 Base
class 析构函数不是 virtual
& 基础 class 指针指向 Derived
class 对象所以默认情况下析构函数将是称为 Base
class,除非它被标记为 virtual
。这将泄漏 Derived
class 数据成员 d
的动态分配内存并调用 未定义行为 .
让我列一个清单...
Base
析构函数不是virtual
.- 它使用原始指针而不是智能指针
- 事实上,它根本不需要指针,
new
和delete
- 因此,它实际上不需要析构函数。
- 也
Derived
拼写为Dervied
- ...它无法编译。
你的基础 class 析构函数应该声明为虚拟的,看起来像
cpp
virtual ~Base()
{
std::cerr<<"destroying Base " << this << std::endl;
delete i;
}
你可以在这里找到它http://www.programmerinterview.com/index.php/c-cplusplus/virtual-destructors/
当您可以通过指向基 class:
的指针删除派生 class 的实例时,虚拟析构函数很有用there is a major problem with the code above: the destructor for the "Derive" class does not get called at all when we delete
basePtr
,
派生对象的构造遵循构造规则,但是当我们删除"b"指针(基指针)时,我们发现只有基析构函数是call.But,这肯定不会发生。
为了做适当的事情,我们必须使基本析构函数成为虚拟的。它类似于运行时的多态性,因此编译器会发现这是一个基指针但指向派生的class,并自动为它绑定派生的class析构函数[=14] =]