我有一个非常奇怪的问题,我希望有人遇到过。
class Letter
{
public:
Letter()
virtual ~Letter()
virtual std::string get() const = 0;
};
class A : public Letter
{
public:
A()
~A()
virtual std::string get() const { return "A"; }
};
class Board
{
public:
Board(){}
~Board()
{
std::cout << "Removing: " << letter->get() << std::endl;
delete letter;
}
void setLetter(Letter * l) { letter = l }
private:
Letter * letter;
}
int main()
{
Board b;
b.setLetter(new A());
}
当Board在析构函数中调用虚函数letter-&gt; get()的行超出范围时,程序会导致seg错误。我正在使用gcc 4.1.2。有什么想法吗?
更新
好吧,看起来实际代码中实际发生的事情就等同于:
class Board
{
public:
Board(){}
~Board()
{
std::cout << "Removing: " << letter->get() << std::endl;
}
void setLetter(Letter * l) { letter = l; }
private:
Letter* letter;
};
int main()
{
Board b;
A a;
b.setLetter(&a);
return 0;
}
在这种情况下,当调用虚函数时,A已经超出范围。
答案 0 :(得分:1)
我只能猜测你是在尝试将从get()返回的std :: string转换为char *。否则我认为没有理由崩溃。
答案 1 :(得分:0)
#include <iostream>
#include <string>
using namespace std;
class Letter
{
public:
Letter() {}
virtual ~Letter() {}
virtual std::string get() const = 0;
};
class A : public Letter
{
public:
A() {}
~A() {}
virtual std::string get() const { return "A"; }
};
class Board
{
public:
Board(){}
~Board()
{
std::cout << "Removing: " << letter->get() << std::endl;
delete letter;
}
void setLetter(Letter * l) { letter = l; }
private:
Letter * letter;
};
int main()
{
Board b;
b.setLetter(new A());
return 0;
}
gcc 4.5.2没问题。
答案 2 :(得分:0)
我没有意识到对象是从堆栈传递给setLetter()的,所以A在b之前超出了范围。
Board b;
A a;
b.setLetter(&a);
答案 3 :(得分:-1)
有些编译器不允许Plain C / C ++构造函数或析构函数调用虚方法,似乎也不像(ANSI)C ++规范。它不推荐。
有时候这个要求很有用。像Object Pascal显式这样的语言允许在构造函数和析构函数中调用虚方法。
你可以做的一件事是使用“假虚拟构造模式”:
class MyClass
{
public:
// constructor
MyClass
{
// anything but virtual methods
}
// destructor
~MyClass
{
// anything but virtual methods
}
virtual void MyFakeConstructor()
{
MyVirtualMethod();
}
virtual void MyFakeDestructor()
{
MyVirtualMethod();
}
virtual void MyVirtualMethod()
{
// more stuff
}
// more members
}
int main(char[][] Args)
{
MyClass MyObject = new MyClass();
MyObject->MyFakeConstructor(); // <-- calls "MyVirtualMethod()"
MyObject->DoSomething1();
MyObject->DoSomething2();
MyObject->DoSomething3();
MyObject->MyFakeDestructor(); // <-- calls "MyVirtualMethod()"
delete MyObject;
return 0;
} // int main()
另一种解决方案是,您可以安排代码,以便在析构函数之外显式调用虚方法。
干杯。