【发布时间】:2016-08-11 23:34:56
【问题描述】:
我有一个使用原始指针实现的双向对象关联,它可以正常工作。然后我决定用智能指针重构我的代码,突然之间一个字符串成员 (depName) 的一个类(部门)在对象初始化后不再可访问。我检查了参数是否正确传递,并且在构造函数中一切正常。成员获得预期值。但之后它不再可访问,并且除了之前运行平稳的代码现在崩溃了。我不知道为什么。
编辑:Manager 类中使用的字符串变量名似乎也发生了同样的情况。结束编辑
- 代码编译时没有错误甚至警告。
- 我正在使用 qt creator 3.3.0 和 mingw 编译器 5.4.0
- 系统声称存在“分段错误”。
这是我的代码(很抱歉,我尽量减少了):
在头文件中:
class Manager;
class Department
{
private:
string depName;
shared_ptr<Manager> head;
vector <shared_ptr<Manager>> depMembers;
public:
Department(string depName, shared_ptr<Manager> head);
virtual ~Department();
string getDepName() const;
void setDepName(const string &value);
void addMember(shared_ptr<Manager> newMember);
void removeMember(shared_ptr<Manager> who);
const shared_ptr<Manager>getHead() const;
void setHead(shared_ptr<Manager>value);
double sumOfIncome();
void show();
};
//--------------------------------
class Department;
class Manager
{
private:
string name;
float salary;
float bonus;//Bonus ist ein Prozentsatz
weak_ptr<Department> myDepartment;
// Department * myDepartment; //With this raw pointer the code still worked*
public:
Manager(string, float, float);
virtual ~Manager();
float income()const ;
string toString()const ;
double calcBonus() const;
shared_ptr<Department> getMyDepartment() const;
void setMyDepartment(shared_ptr<Department> abt);
float getSalary() const;
string getName() const;
};
在 cpp 文件中: 部门.cpp
//---------------------------------------------------
Department::Department(string depName, shared_ptr<Manager>head)
:depName(depName),head(nullptr)
{
this->setHead(head);
cout << "\nIn constructor parameter depName: " + depName;
cout << "\n instancevariable " + this->depName << endl;
}
//--------------------------------
Department::~Department()
{}
//--------------------------------
string Department::getDepName() const
{
return this->depName;
}
//--------------------------------
void Department::setDepName(const string &value)
{
depName = value;
}
//--------------------------------
void Department::addMember(shared_ptr<Manager> newMember)
{
depMembers.push_back(newMember);
}
//--------------------------------
void Department::removeMember(shared_ptr<Manager> who)
{
vector<shared_ptr<Manager>>::iterator itMember = depMembers.begin();
//Iterator must be dereferenced to access data
while( *itMember != who){
itMember++;
}
if( *itMember == who)
depMembers.erase( itMember);
}
//--------------------------------
const shared_ptr<Manager> Department::getHead() const
{
return head;
}
//--------------------------------
void Department::setHead(shared_ptr<Manager>value)
{
if( head != nullptr && head->getMyDepartment()!= nullptr)
head->setMyDepartment(nullptr);//department of old head is deleted
//new head of department assigned
head = value;
//bidirektionaler access
if(head !=nullptr)
head->setMyDepartment( shared_ptr<Department>(this));
}
//--------------------------------
double Department::sumOfIncome()
{
double sum = 0;
for(unsigned int i=0; i < depMembers.size(); i++){
sum += depMembers[i]->getSalary() ;
}
return sum;
}
//--------------------------------
void Department::show()
{
cout <<"----------------" << endl;
cout << "Department: " << this->depName << " run by " << head->getName()<<endl;
cout <<"----------------" << endl;
cout << "Members: " << endl;
cout <<"----------------" << endl;
cout << head->toString() << endl;
for( unsigned int i=0; i < depMembers.size() ; i++){
cout <<"----------------" << endl;
cout << depMembers[i]->toString()<< endl;
}
cout <<"----------------" << endl;
}
manager.cpp
//---------------------
float Manager::getSalary() const
{
return salary;
}
//----------------------------------
string Manager::getName() const
{
return name;
}
//----------------------------------
Manager::Manager(string n, float s, float bon)
:name(n),salary(s), bonus(bon)
{}
//----------------------------------
Manager::~Manager(){}
//----------------------------------
float Manager::income()const
{
return (salary + calcBonus() );
}
//----------------------------------
string Manager::toString() const
{
stringstream ss;
ss << name << "\n heads the department ";
shared_ptr<Department> dep = myDepartment.lock();
if( dep !=nullptr)
ss<< dep->getDepName();
else ss << " NONE ";
ss << "\nBonus: " << calcBonus();
ss << "\nIncome: " << income();
return ss.str();
}
//----------------------------------
double Manager::calcBonus()const
{
shared_ptr<Department> dep = myDepartment.lock();
if(dep != nullptr)
return dep->sumOfIncome()* bonus;
else
return 0;
}
//----------------------------------
shared_ptr<Department> Manager::getMyDepartment() const
{
// if( !meineAbteilung->expired())
return myDepartment.lock();
}
//----------------------------------
void Manager::setMyDepartment( shared_ptr<Department> dep)
{
myDepartment = dep;
}
//----------------------------------
试运行:
int main(){
shared_ptr<Department> itDepartment
= make_shared<Department>("IT",make_shared<Manager>("Julia", 66066, 0.15));
itDepartment->show();
return 0;
}
【问题讨论】:
-
包含您提到的崩溃的回溯会很有帮助。
-
我不知道如何提供。你的意思是堆栈跟踪吗?我知道如何在 eclipse (Java) 中做到这一点,但在 QT 中不知道。但我可以提供以下信息:程序崩溃,试图在 show 方法中访问管理器的名称,这也不再可用。系统声称存在分段错误。
-
你可以在 gdb 上运行它,但是,如果你想以图形方式运行它,只需在调试模式下运行项目(Qt Creator 上的
F5),它会在崩溃时停止。然后,它将显示调用堆栈。更多信息:doc.qt.io/qtcreator/creator-debug-mode.html
标签: qt c++11 shared-ptr bidirectional weak-ptr