Jea*_*uys 8 c++ gcc abstract-class linker-errors
我有一个链接错误,其中链接器抱怨我的具体类的析构函数正在调用其抽象的超类析构函数,其代码缺失.
这是在XCode的Mac OS X上使用GCC 4.2.
我看到了g ++未定义的对typeinfo的引用,但它并不完全相同.
这是链接器错误消息:
Undefined symbols:
"ConnectionPool::~ConnectionPool()", referenced from:
AlwaysConnectedConnectionZPool::~AlwaysConnectedConnectionZPool()in RKConnector.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
这是抽象基类声明:
class ConnectionPool {
public:
static ConnectionPool* newPool(std::string h, short p, std::string u, std::string pw, std::string b);
virtual ~ConnectionPool() =0;
virtual int keepAlive() =0;
virtual int disconnect() =0;
virtual sql::Connection * getConnection(char *compression_scheme = NULL) =0;
virtual void releaseConnection(sql::Connection * theConnection) =0;
};
Run Code Online (Sandbox Code Playgroud)
这是具体的类声明:
class AlwaysConnectedConnectionZPool: public ConnectionPool {
protected:
<snip data members>
public:
AlwaysConnectedConnectionZPool(std::string h, short p, std::string u, std::string pw, std::string b);
virtual ~AlwaysConnectedConnectionZPool();
virtual int keepAlive(); // will make sure the connection doesn't time out. Call regularly
virtual int disconnect(); // disconnects/destroys all connections.
virtual sql::Connection * getConnection(char *compression_scheme = NULL);
virtual void releaseConnection(sql::Connection * theConnection);
};
Run Code Online (Sandbox Code Playgroud)
毋庸置疑,所有这些成员都得到了实施.这是析构函数:
AlwaysConnectedConnectionZPool::~AlwaysConnectedConnectionZPool()
{
printf("AlwaysConnectedConnectionZPool destructor call"); // nothing to destruct in fact
}
Run Code Online (Sandbox Code Playgroud)
也许是工厂例行程序:
ConnectionPool* ConnectionPool::newPool(std::string h, short p, std::string u, std::string pw, std::string b)
{
return new AlwaysConnectedConnectionZPool(h, p, u, pw, b);
}
Run Code Online (Sandbox Code Playgroud)
我可以通过人为地使我的抽象基类具体化来解决这个问题.但我宁愿做更好的事情.任何的想法?
谢谢
小智 34
即使将析构函数声明为纯虚函数,也必须为其提供实现.虽然您无法直接实例化抽象类,但在实例化其派生(具体)类之一时,它始终会被实例化.因此在某些时候这样的实例将被破坏,因此需要一个析构函数.纯虚析构函数的实现可以(通常是)一个空函数:
ConnectionPool::~ConnectionPool() {
}
Run Code Online (Sandbox Code Playgroud)
小智 5
即使在抽象类中,您也不希望析构函数是纯虚拟的。这是因为当调用具体子类的析构函数时它将被调用。
我们使用以下模式。
foo.h
class AbstractBaseClass {
public:
virtual ~AbstractBaseClass();
virtual void method1() = 0;
virtual void method2() = 0;
protected:
AbstractBaseClass() {
}
};
Run Code Online (Sandbox Code Playgroud)
foo.cpp
AbstractBaseClass::~AbstractBaseClass() {
}
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅此常见问题解答。