我有一個抽象類Base和派生類Derived:
class Base
{
public:
Base(int n) :_n(n) { _arr = new int[n]; }
virtual ~Base() { delete[] _arr; }
Base(Base&& other) { _n = other._n; _arr = other._arr; other._arr = nullptr; other._n = 0; }
virtual void func() = 0;
private:
int _n;
int* _arr;
};
class Derived : public Base
{
public:
Derived(int m, int n) : Base(n), _m(m) { _arr = new int[m]; }
~Derived() { delete[] _arr; }
Derived(Derived&& other) : Base(std::move(other)) { _m = other._m; _arr = other._arr; other._arr = nullptr; other._m = 0; }
void func() override { cout << "func"; }
private:
int _m;
int* _arr;
};
然后我有一個Bag包含右值參考的類Base:
class Bag
{
public:
Bag(Base&& b) : _b(std::move(b)) {}
void func() { _b.func(); }
private:
Base&& _b;
};
int main()
{
Bag bag(Derived(1, 1));
bag.func();
}
我使用右值參考成員_b,因為我只想在Bag的建構式中獲取一個臨時物件。但是,在bag.func()我收到錯誤訊息后:呼叫了 abort() 。似乎在臨時物件被破壞后,bag._b的型別從Derived變為。BaseDerived(1,1)
bag.func()在我洗掉后作業virtual ~Base() { delete[] _arr; }。為什么?如果我需要Base的解構式,我該如何更改我的代碼?
uj5u.com熱心網友回復:
Base&& _b是對臨時物件的參考,當該臨時物件在行尾被銷毀時,Bag bag(Derived(1, 1));該參考將變為懸空參考,并且對該參考的任何使用都是未定義的行為。
您可以更改_b為一個值,但這會分割您的物件。
如果你想存盤一個多型物件,唯一真正的選擇是使用指標(最好是智能指標)。例如:
class Bag
{
public:
Bag(std::unique_ptr<Base>&& b) : _b(std::move(b)) {}
void func() { _b->func(); }
private:
std::unique_ptr<Base> _b;
};
int main()
{
Bag bag(std::make_unique<Derived>(1, 1));
bag.func();
}
請注意,您還應確保Base并Derived遵循五規則,否則在分配物件時可能會遇到問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/537168.html
標籤:C C 11右值
