編輯:事實證明,在我的 Sunflower 實作中,我將函式命名為 grow() 而不是 growImpl(),因此編譯器沒有找到實作并將 Sunflower 視為抽象。這個問題可以關閉。
我正在嘗試動態創建從介面繼承的類的物件。我試圖將這個物件包裝在一個唯一的指標中(我不允許使用new)并回傳它。
我收到以下錯誤:
/Library/Developer/CommandLineTools/SDKs/MacOSX12.1.sdk/usr/include/c /v1/memory:2099:32: error: allocating an object of abstract class type 'Sunflower'
return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
介面有一些純虛函式。我知道當一個函式被宣告為純虛擬時,它必須有一個實作。但我添加了一個實作只是為了讓它編譯。所以,我不確定為什么 Sunflower 應該是 Flower 介面的實作時被認為是抽象類。
如果我從花類中洗掉 virtual 和 const = 0 關鍵字,則會收到以下錯誤:
/Library/Developer/CommandLineTools/SDKs/MacOSX12.1.sdk/usr/include/c /v1/memory:2099:32: error: no matching constructor for initialization of 'Sunflower'
return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...));
如何確保向日葵不被視為抽象并成功創建唯一指標?
這是花的界面:
#include <algorithm>
#include <numeric>
#include <iostream>
using namespace task3;
std::unique_ptr<Flower>
createSunflower(ex5::task3::Location location, ex5::task3::Color color);
class Flower{
public:
Flower();
Flower(Location _location, Color _color) : location(_location.getRow(), _location.getColumn()), color{_color} { }
Flower(const Flower&) = delete;
Flower(Flower&&) = delete;
virtual ~Flower() = default;
Flower& operator=(const Flower&) = delete;
Flower& operator=(Flower&&) = delete;
ex5::task3::Location getLocation(){return location;}
void grow(const Garden& garden){
return growImpl(garden);
}
[[nodiscard]] std::unique_ptr<Flower> spread(const Garden& garden){
return spreadImpl(garden);
}
Color getColor(){return color;}
Location location;
Color color;
private:
virtual void growImpl(const Garden&) ;
[[nodiscard]] virtual std::unique_ptr<Flower> spreadImpl(const Garden&) ;
};
這個的實作在這里,它包含向日葵類。給我錯誤的行在函式中createSunflower()。我剛剛添加了 make_uniquespread()以提供實作。但是在createSunflower有或沒有實作spread()and的情況下,這行給了我錯誤grow():
using namespace task3;
class Sunflower final: public Flower{
//public:
private:
void grow(const Garden& garden) const override{
cout << endl;
}
[[nodiscard]] std::unique_ptr<Flower> spread(const Garden& garden)const override {
return std::make_unique<Flower> ({0,0}, Color::BLACK);
}
};
std::unique_ptr<Flower>
createSunflower(ex5::task3::Location location, ex5::task3::Color color){
return std::make_unique<Sunflower>(location, color);
}
這里定義了列舉和結構,這些是給我的,我無法更改它們:
namespace task3{
class Garden {
public:
plant(){
//do stuff
}
private:
std::vector<std::unique_ptr<Flower>> flowers;
};
class Location {
public:
Location(size_t row, size_t column)
: locationPair{row, column}
{ }
[[nodiscard]] size_t getRow() const noexcept { return locationPair.first; }
[[nodiscard]] size_t getColumn() const noexcept { return locationPair.second; }
private:
std::pair<size_t, size_t> locationPair;
};
enum class Color {
WHITE, RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET, BLACK
};
}}
uj5u.com熱心網友回復:
std::make_unique<T>()創建 的實體T,這意味著T不能是抽象型別。
因此,在 內部,當是抽象型別時Sunflower::spread(),呼叫std::make_unique<Flower>(...);將不起作用。Flower在這種情況下,您必須實體化一個派生類,例如
return std::make_unique<Sunflower>(...);
spread()回傳一個unique_ptr<Flower>。只要具有解構式(在您的示例中就是這樣),就可以將Aunique_ptr<Sunflower>分配給。unique_ptr<Flower>Flowervirtual
就像你的createSunflower()功能正在做的那樣。實際上,您可以簡單地Sunflower::spread()呼叫createSunflower(),例如:
std::unique_ptr<Flower> createSunflower(ex5::task3::Location, ex5::task3::Color);
class Sunflower final: public Flower{
//public:
private:
...
[[nodiscard]] std::unique_ptr<Flower> spread(const Garden&) const override {
return createSunflower({0,0}, Color::BLACK));
}
};
std::unique_ptr<Flower>
createSunflower(ex5::task3::Location location, ex5::task3::Color color){
return std::make_unique<Sunflower>(location, color);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/524183.html
上一篇:如何讓繼承的函式使用區域變數
下一篇:如何使用每個回圈設定資料驗證
