我有一种情况,我有一个shared_ptr到子类的基础。
当shared_ptr去删除指针时,只调用父析构函数。
父母的破坏者是虚拟的,孩子不是,虽然我已经尝试了所有的组合。
我在valgrind中有程序,它表明在创建对象时在新语句中创建了内存。我知道正在调用父析构函数,但孩子不是。
这是孩子:
class NetworkUserAgent : public bbs::UserAgent
{
friend class Server;
public:
NetworkUserAgent(boost::asio::io_service &ioService, size_t _szBuffer=512u);
~NetworkUserAgent();
void asyncRead();
void doneRead(std::shared_ptr< std::vector<char> > pBuf,
const boost::system::error_code &error, size_t byTrans);
void writeTo(const std::string &msg);
void doneWrite(const boost::system::error_code &error, size_t byTrans);
void close();
private:
boost::asio::ip::tcp::socket socket_;
const size_t szBuffer;
};
父母:
class UserAgent
{
public:
//'structors
UserAgent();
virtual ~UserAgent();
//commication
virtual void writeTo(const std::string &msg)=0;
std::function<void(std::string&)> dataRead;
//user management
void login(AccessLevel _accessLevel, int userId, const std::string &_userName);
void logout();
//Accessors
AccessLevel UserAccessLevel() const;
const std::string &UserName() const;
const int &UserId() const;
bool LoggedIn() const;
//shared to allow reference to child type
std::shared_ptr<ContextAgentData> contextAgentData;
private:
std::string userName;
int userId;
AccessLevel accessLevel;
};
用法:
void Server::reset()
{
shared_ptr<NetworkUserAgent> client (new NetworkUserAgent(ioService));
acceptor_.async_accept(client->socket_,
[=] (const boost::system::error_code &error)
{ this->clientAccepted(client, error); }
);
}
void Server::clientAccepted(shared_ptr<NetworkUserAgent> client,
const boost::system::error_code &error)
{
if(error) return;
cout << "[] New client has connected" << endl;
//Generalise to Network useragent
shared_ptr<UserAgent> uaClientPtr=client;
context->receiveUserAgent(uaClientPtr);
client->asyncRead();
reset();
}
The rest of the code can be seen here
谢谢。
另请注意,上面的代码仍在进行中。
编辑:我错误地调用了子析构函数,
NetworkUserAgent::~NetworkUserAgent()
{
this->close();
}
void NetworkUserAgent::close()
{
if(!socket_.is_open()) return; //socket is already closed
//one or more of these functions are probably redundant
cout << "send request" <<endl;
socket_.shutdown(ip::tcp::socket::shutdown_send);
cout << "cancel" <<endl;
socket_.cancel();
cout <<"close"<<endl;
socket_.close();
cout << "done" <<endl;
}
编辑: 我做了更多测试,我担心问题比我希望的复杂。当项目被销毁时,将调用析构函数,但问题是,一旦UserAgent进入系统,它就不会被销毁。有些事情正在停止被摧毁。
如果它与selfragent的几个容器shared_ptr有区别,那么当contains是destroy时,被调用的元素的析构函数是什么?
请让我知道我还能提供什么来解决问题。
答案 0 :(得分:2)
在UserAgent中有一个dataRead std :: function,它最终被设置为一个包含std :: shared_ptr的lambda,以阻止它自我形式的破坏。我添加了一个close()方法并将std :: function设置为默认值。
现在一切都很顺利,它删除了很好的
感谢您的所有帮助
答案 1 :(得分:0)
我怀疑你的对象正在切片,但我没有可以测试的环境。
尝试以下方法之一:
shared_ptr<UserAgent> uaClientPtr = boost::static_pointer_cast<UserAgent>(client);
shared_ptr<UserAgent> uaClientPtr = boost::dynamic_pointer_cast<UserAgent>(client);
答案 2 :(得分:0)
在void Server::reset()
auto_ptr
就足够了。
在第二种情况下,我会做以下事情:
void Server::clientAccepted(shared_ptr<NetworkUserAgent> client, const boost::system::error_code error)
{
if(error) return;
cout << "[] New client has connected" << endl;
context->receiveUserAgent(client);
client->asyncRead();
this->reset();
}