我一直在創建命名變數,以便能夠將它們的地址傳遞給需要指標的建構式,但我希望能夠在建構式或其他函式中創建它們,然后將它們的地址傳遞給需要指標的建構式.
我正在使用 C 20,并且我有以下類:
#include <iostream>
#include <string>
#include <vector>
#include <random>
using std::string, std::cout, std::cin, std::endl, std::vector;
class symbol {
public:
enum symbolKind {
null,
terminal,
sequence,
weighted,
random
};
protected:
symbolKind kind;
public:
virtual string evaluate() const = 0;
symbolKind getKind() {
return kind;
}
};
class nullSymbol : public symbol {
public:
nullSymbol() {
kind = symbol::null;
}
string evaluate() const override {
return "";
}
};
class terminalSymbol : public symbol {
private:
string termString;
public:
terminalSymbol(string pString) {
kind = symbol::terminal;
termString = pPhoneme;
}
string evaluate() const override {
return termString;
}
};
class sequenceSymbol : public symbol {
private:
vector<symbol*> symArray;
public:
sequenceSymbol(vector<symbol*> pArr) {
kind = symbol::sequence;
symArray = pArr;
}
string evaluate() const override {
string retStr = "";
for (symbol* current : symArray) {
retStr = current->evaluate();
}
return retStr;
}
};
class weightedSymbol : public symbol {
private:
float weight;
symbol* subSym;
public:
weightedSymbol(symbol* pSym, float pWeight) {
kind = symbol::weighted;
subSym = pSym;
weight = pWeight;
}
string evaluate() const override {
return subSym->evaluate();
}
float getWeight() {
return weight;
}
};
class randomSymbol : public symbol {
private:
vector<weightedSymbol*> symArray;
public:
randomSymbol(vector<weightedSymbol*> pArr) {
kind = symbol::random;
symArray = pArr;
}
string evaluate() const override {
float sum = 0.0;
for (weightedSymbol* current : symArray) {
sum = current->getWeight();
}
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(0.0, sum);
float randomResult = dis(gen);
float prev = 0;
for (weightedSymbol* current : symArray) {
if (randomResult < (prev = current->getWeight())) return current->evaluate();
}
}
};
我一直在創建這樣的符號:
terminalSymbol term_a("a");
terminalSymbol term_b("b");
sequenceSymbol seq_ab({ &term_a, &term_b});
cout << "ab test: " << seq_ab.evaluate() << endl;
但我希望能夠這樣做或類似的事情:
sequenceSymbol seq_ab_2({&terminalSymbol("a"), &terminalSymbol("b")});
cout << "ab test 2: " << seq_ab_2.evaluate() << endl;
'&' requires l-value這會在 Visual Studio 中創建一個錯誤。
這是一個非常簡單的示例,通常會創建比這更多的變數。在這種情況下,地址被傳遞給std::vector<weightedSymbol*>()建構式;這與weightedSymbol()建構式相同,它也需要一個指標。這不僅適用于建構式(如果有另一種實作相同功能的方法,它甚至不需要與建構式本身一起使用),但我想要一種在函式中創建堆物件然后回傳指標的方法對于在這種情況下作業的他們。可能我需要更改類本身才能使其正常作業,它們應該只提供相同的功能。
最后,我想根據用戶輸入動態創建這些符號物件。
我在網上搜索并嘗試使用一堆不同的東西,但沒有設法獲得我想要的功能。什么是實作這一點的好方法?可能有一個常用的技術/成語我可以使用,如果可以,請詳細解釋給我,以便我也可以在其他專案中使用它。
uj5u.com熱心網友回復:
您通過指標傳遞的物件需要以某種方式銷毀。在此代碼段中,只要您退出塊,它們就會自動銷毀:
terminalSymbol term_a("a");
terminalSymbol term_b("b");
sequenceSymbol seq_ab({ &term_a, &term_b});
如果您創建沒有命名變數的物件會發生什么?您的類永遠不會洗掉您通過指標傳遞的物件,因此呼叫者應該負責管理每個物件的生命周期。
您的問題的一種解決方案是將物件包裝到任何型別的智能指標中。例如:
class sequenceSymbol : public symbol {
public:
sequenceSymbol(vector<shared_ptr<symbol>> pArr);
};
sequenceSymbol seq_ab_2({
std::make_shared<terminalSymbol>("a"),
std::make_shared<terminalSymbol>("b")
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/430753.html
