如果我有一个基类和一个派生类,并且我在父虚拟中删除了析构函数,但是实例化了一个类型为subclass的对象,当它被销毁时它会调用父析构函数(自虚拟)?如果我还在派生类中声明了析构函数,它是否会调用析构函数(base和derived).提前致谢 :-).
我的问题的第二部分是关于第一部分.为什么需要将基类析构函数声明为虚拟.建设者不要循环起来.它们没有相同的名称,所以需要它的位置?对于破坏者来说它不应该是一样的,或者默认只有一个叫做破坏者?通过后期绑定也可以检测到所有类和对象是由哪个组成的?
编辑:我的问题不仅仅是关于虚拟析构函数,而是为什么它需要被声明为虚拟,因为它们都应该默认调用.
我试图从C++中的java中学习一些面向对象的编程方面.不过我有在使用一些困难dynamic_cast
,我会用instanceof
Java编写的.
我有一个基类Cell
和一个派生(抽象)类Obstacle
.我已经像这样定义了它:Obstacle : public Cell
并且Obstacle
包含一个纯虚拟析构函数.现在在Cell
课堂上我想实现一个方法bool Cell::isAccesible()
.我已经实现了如下:
bool Cell::isAccessible() {
Obstacle *obs = dynamic_cast<Obstacle*>(this);
if (obs != NULL) return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
"运行时dynamic_cast的操作数必须具有多态类类型".
我想要实现这个的方式有什么问题?任何指导表示赞赏.
所以我不是一个专业的开发人员,但我定期编程.我正在寻找编写代码,并寻找一些关于管理解析器的建议,该解析器正在读取文本文件,将每行视为字符串,并尝试确定该行的输入.任何给定的行可能是1000多个不同的关键字之一,这是困难的部分.一旦我有了这个关键字,我觉得必须有一个更有效的方法来确定它是什么,而不是实现1000 if-else语句或1000 case-break语句.一旦我匹配给定的关键字,我计划跳转到一个例程,该例程实例化该关键字类型的对象.在找到我的目标之前,我不想进行999次测试,这只是我觉得的浪费.我尝试按字母顺序拆分它,这大大减少了它,但仍然存在无法管理的大量if-else语句.
我已经发现我不能嵌套超过128个if-else语句,所以我当前的替代方案是1000个只是"if"语句没有匹配"else"语句,我知道这是一个不好的做法.所以这是我当前代码的概括:
if (keyword_str.compare(keyword1)) {
Parse(keyword1); // A general routine to parse all these similarly formatted keywords
}
if (keyword_str.compare(keyword2)) {
Parse(keyword2);
}
if (keyword_str.compare(keyword3)) {
Parse(keyword3);
}
//
//
//
if (keyword_str.compare(keyword999)) {
Parse(keyword999);
}
if (keyword_str.compare(keyword1000)) {
Parse(keyword1000);
}
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激!谢谢!
好的,所以这就是我所处的观点,但仍然有点迷失在如何使用地图来确定对象类型,然后实例化该对象.以下是一些代码段:
class baseClass
{
public:
baseClass();
~baseClass();
};
//
// keyword1 class declaration
class keyword1 : public baseClass
{
public:
// Constructors
keyword1 () { cout << "keyword1 constructor..." << endl;}
~keyword1 () { cout << …
Run Code Online (Sandbox Code Playgroud) #include <vector>
enum ListOfGameStates
{
// List of game states
};
class GameState()
{
public:
GameStates(); // Initializes protected (global) variables
virtual ListOfGameStates run() = 0;
protected:
// Heavyweigh resource managers containing all resources and other global vars
}
class GameStateManager()
{
public:
GameStateManager(); // Creates all game states
~GameStateManager(); // Deletes all game states
void run(); // Switches from one state to another state
private:
// A vector of raw pointers to game states. GameState is a base class. …
Run Code Online (Sandbox Code Playgroud) stackoverflow上有这个问题,它主张Scott Meyers规则只有在该类中有虚函数时才使析构函数成为虚拟.
我在一家拥有大型框架的公司工作,如果您的课程未来可以扩展,那么在编码时不清楚.在那个时间点,也可能无法更改该类(因为它是已发布的包的一部分).
现在想象以下场景:
class A {
public:
A();
virtual ~A();
virtual m();
};
class B : public A {
public:
B();
~B();
};
class C : public B {
public:
C();
virtual ~C();
virtual m();
};
Run Code Online (Sandbox Code Playgroud)
所以我创造了class B
,到现在为止,它无法改变.现在class C
已创建,并用作B
:
B * b = new C();
delete b;
Run Code Online (Sandbox Code Playgroud)
会发生什么事情,C的析构函数永远不会被调用,对吧?
在这种情况下:一个类总是应该有一个虚拟析构函数?
是否存在任何有效且可用的情况,这将迫使您不要virtual
在析构函数之前使用关键字。
class Base {
public:
virtual ~Base() { ... } // `virtual` causes error (not compile time or syntax) or wrong behaviour
// could contain other fields
};
// some example
Run Code Online (Sandbox Code Playgroud) 我在玩代码
struct A {
char a[20000];
A() { a[0] = 'A'; }
~A() {}
};
struct B : A {
char a[20000];
B() { a[0] = 'B'; }
~B() {}
};
int main() {
A *pA = new A;
A *pB = new B;
delete pA;
delete pB;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有人写道(为什么我们需要一个带有动态内存的虚拟析构函数?)它应该引起内存泄漏,但事实并非如此。我使用g ++,然后使用valgrind --leak-check = full --show-leak-kinds = all --track-origins = yes --verbose --log-file = valgrind-out.txt并获取
HEAP SUMMARY:
in use at exit: 0 bytes …
Run Code Online (Sandbox Code Playgroud) 正如答案所指出的,这是我犯的一个愚蠢的错误,与多态性或智能指针无关。更正后的版本在接受的答案中。
==============原始问题==================
我正在尝试使智能指针与多态一起工作。在下面的原型代码中,纯virtual
函数的实现Base::print()
应该在Derived
对象的内存块中。DerivedWrap
可以访问指向Derived
对象的指针。
为什么不能DerivedWrap::print()
访问函数实现?
using namespace std;
class Base
{
public:
virtual void print() = 0;
};
class Derived : public Base
{
public:
Derived(int in) : i(in) {}
void print() {
cout << "int is " << i << endl;
}
private:
int i;
};
class DerivedWrap
{
public:
DerivedWrap() : DerivedWrap(make_unique<Derived>(2)) {}
DerivedWrap(unique_ptr<Base> pBase) : _pBase(move(pBase)) {}
void print()
{
_pBase->print();
}
private:
unique_ptr<Base> …
Run Code Online (Sandbox Code Playgroud) 在基类构造函数中,我希望实例是派生类。我可以做这样的事情吗?
class InterfaceClass // Final user only sees this class
{
enum class TYPE
{
CHILDONE
};
public:
InterfaceClass(TYPE);
virtual void hello_world() = 0;
virtual void print_class();
};
class ChildOne : public InterfaceClass
{
public:
ChildOne() = default;
void hello_world();
private:
};
InterfaceClass::InterfaceClass(TYPE type)
{
if (type == CHILDONE)
this = new ChildOne();
else
throw "NOT HANDLED";
}
void InterfaceClass::hello_world() {
std::cout << "Hello world from InterfaceClass" << std::endl;
}
void InterfaceClass::print_class() {
std::cout << "Not implemented" << std::endl;
} …
Run Code Online (Sandbox Code Playgroud) c++ ×10
class ×2
destructor ×2
polymorphism ×2
c++11 ×1
casting ×1
constructor ×1
inheritance ×1
memory-leaks ×1
oop ×1
parsing ×1
performance ×1
raii ×1
raw-pointer ×1
virtual ×1