1
有沒有寫一個拷貝構造一類(比方說,Copyable
,即持有std::unique_ptr
到Base
類(但一個真正的方式存儲Derived
對象。是否有可能有一個複製可構造類持有std :: unique_ptr <Base>避免切片沒有基地暴露「克隆」功能?
快速測試顯示了預期的切片時,因爲Copyable
不知道它的控股真正的類型,所以我想需要一個clone
方法,但我不知道是否有辦法讓編譯器在一些更好的方式來處理這個
縱切代碼:?
#include <algorithm>
#include <iostream>
#include <memory>
struct Base
{
Base(int i = 0) : i(i) {}
virtual ~Base() = default;
int i;
virtual int f() { return i; }
};
struct Derived : Base
{
Derived() = default;
virtual int f() override { return 42; }
};
struct Copyable
{
Copyable(std::unique_ptr<Base>&& base) : data(std::move(base)) {}
Copyable(const Copyable& other)
{
data = std::make_unique<Base>(*other.data);
}
std::unique_ptr<Base> data;
};
int main()
{
Copyable c(std::make_unique<Derived>());
Copyable c_copy = c;
std::cout << c_copy.data->f() << '\n';
}
的clone
代碼:
#include <algorithm>
#include <iostream>
#include <memory>
struct Base
{
Base(int i = 0) : i(i) {}
virtual ~Base() = default;
int i;
virtual int f() { return i; }
virtual Base* clone() { return new Base(i); }
};
struct Derived : Base
{
Derived() = default;
virtual int f() override { return 42; }
virtual Derived* clone() override { return new Derived(); }
};
struct Copyable
{
Copyable(std::unique_ptr<Base>&& base) : data(std::move(base)) {}
Copyable(const Copyable& other)
{
data.reset(other.data->clone());
}
std::unique_ptr<Base> data;
};
int main()
{
Copyable c(std::make_unique<Derived>());
Copyable c_copy = c;
std::cout << c_copy.data->f() << '\n';
}
顯然克隆代碼工作。事情是,這裏有一些我想避免的東西:
- raw
new
。 - 需要成爲界面一部分的隨機函數。
- 該函數返回一個原始指針。
- 此類想要可複製的每個用戶都需要調用此函數。
那麼,有沒有「乾淨」的替代?
注意我想使用智能指針的所有顯而易見的原因,我只需要深刻複製std::unique_ptr
。類似std::copyable_unique_ptr
,將可選移動語義與深層複製拷貝構造函數結合在一起。這是最乾淨的方式嗎?或者這隻會增加混亂?
'std :: copyable_unique_ptr'沒有任何意義。有一個指向可克隆對象的'std :: unique_ptr'使得它更有意義。你有什麼可能是最好的方法。但有幾點:複製構造函數是一個構造函數,所以它可以有一個成員初始化列表。 'clone'函數應該調用copy-constructor,拷貝'* this'。而派生類中的'clone'函數應該返回一個指向基類的指針。 –
@Someprogrammerdude一個'copyable_unique_ptr'如何沒有意義?有很多情況下,你們都希望移動和複製數據,每當你需要它們時。當然,你需要注意'std :: move',但是不可能複製移動類型而不會弄髒接口,這似乎意味着這是一個理智的解決方案。 – rubenvb
@rubenvb當用戶不期待拷貝構造函數被調用的危險是爲什麼'auto_ptr'被棄用的很大一部分。使用'copyable_unique_ptr'的效果會稍差,但它仍然會很糟糕。一個'clonable_unique_ptr'(或者在Deduplicator的答案中是'clone_ptr')不提供拷貝構造函數,但提供了一個'clone()'成員函數,實現了你希望用'copyable_unique_ptr'實現的目標,但是沒有危險。 – hvd