2017-02-08 17 views
0

Я тестирую shared_ptrs и QStrings, и у меня есть сбой, который я не совсем понимаю. Вот код:Сбой программы при доступе к shared_ptr hold QString

#include <QCoreApplication> 
#include <QString> 

#include <iostream> 

class Base { 
public: 
    Base(const QString& str1, const QString& str2, const QString& str3) { 
    member1_ = std::make_shared<Internal>(); 
    (*member1_).i1 = str1; 
    (*member1_).i2 = str2; 
    member2_ = std::make_shared<QString>(str3); 
} 
QString getMember() { return *member2_; } 
QString getInternalMember() { return (*member1_).i1; } 
protected: 
Base(const Base&) = default; 
Base& operator=(const Base&) = default; 
Base(Base&&) = default; 
Base& operator=(Base&&) = default; 

private: 
struct Internal { 
    QString i1; 
    QString i2; 
}; 
std::shared_ptr<Internal> member1_; 
std::shared_ptr<QString> member2_; 
}; 

class Derived : public Base { 
public: 
    Derived(const QString& str1, const QString& str2, const QString& str3) : Base(str1, str2, str3) { 
    derivedMember_ = 1; 
    } 
private: 
    int derivedMember_; 
}; 

int main(int argc, char *argv[]) { 
QCoreApplication a(argc, argv); 
Derived* d1 = new Derived("param1", "param2", "param3"); 
std::cout << "d1 created " << d1->getMember().toStdString() << "-" << d1->getInternalMember().toStdString() << std::endl; 
Derived* d2 = d1; 
delete d1; 
std::cout << "d2 created " << d2->getMember().toStdString() << "-" << d2->getInternalMember().toStdString() << std::endl; 
return a.exec(); 
} 

Почему этот краш? Я использую shared_ptrs, поэтому после того, как счетчик ссылок присваивания должен увеличиться.

Заранее спасибо

+0

Вы копируете указатели, а не объекты. –

+0

Поскольку QString использует [COW] (https://en.wikipedia.org/wiki/Copy-on-write), неясно, почему вы даже попадете в такую ​​ситуацию. Здесь очень мало смысла использовать интеллектуальные указатели - не говоря уже о указателях - в первую очередь. – MrEricSir

+0

@MrEricSir Я хочу, чтобы QString была одинаковой для всех скопированных объектов. Даже если QString использует COW, используя простые указатели, если я его модифицирую, он будет скопирован, а объекты будут иметь разные значения. – RuLoViC

ответ

3

d2 указывает на тот же объект, d1, удалить объект, а затем попытаться вызвать его метод (после удаления)

+0

В этом случае, почему, если я изменяю QString по int, разве это не сбой? – RuLoViC

+1

Это неопределенное поведение. –