![](/img/trans.png)
[英]I want a template function that takes a pointer to member, but I don't want to have to pass the class type nor the member type
[英]I want return type pointer but i want my function to return pointer of derive class
Dragon* Dragon::spawn() {
int x = rand() % 5;
int y;
if (!if_locked(x)) //is a function to see if that id is unlocked because i want some dragon to be generated only if you have certain xp so it will call func again until unlocked id is generated
spawn();
else
y = unlocking(m); // Y is generated form 1-5, I have assigned Id to each derive class whosoever id matches Y that pointer will be returned
if (y == 1) {
GroundDragon* pt;
return pt;
}
if (y == 2) {
WaterDragon* st;
return st;
}
if (y == 3) {
IceDragon*bt;
return bt;
}
if (y == 4) {
FireDragon* ct;
return ct;
}
if (y == 5) {
DarkDragon* dark;
return dark;
}
}
正如你所看到的,我犯了語法錯誤,希望有人能指導我
函數的返回類型是基類,if語句中的所有類都是派生類
所以我以后可以使用這個功能
template<class T>
void spawner(T*) {// I will spawn() fucntion as perimeter at time of call
T = new T;
}
請原諒我,如果我上次發布問題時我重復了這個問題並沒有引起我期待的關注,所以我修改了我的代碼,希望現在很清楚了`
int Dragon::unlocking(Mage m) {
if (m.getxp() <= 50 and m.getxp() <= 100) {
unlock[0] = 1;
cout << "Congratulation GroundDragon unlocked " << endl;
return 1;
}
if (m.getxp() > 100 and m.getxp() < 150) {
unlock[1] = 1;
cout << "Congratulation WaterDragon unlocked " << endl;
return 2;
}
if (m.getxp() > 150 and m.getxp() < 175) {
unlock[2] = 1;
cout << "Congratulation IceDragon unlocked " << endl;
return 3;
}
if (m.getxp() > 175 and m.getxp() < 500) {
unlock[3] = 1;
cout << "Congratulation FireDragon unlocked " << endl;
return 4;
}
if (m.getxp() > 500) {
unlock[4] = 1;
cout << "Congratulation DarkDragon unlocked " << endl;
return 5;
}
}
bool Dragon::if_locked(int x) {
if (unlock[x] == 1) {
return true;
}
else
return false;
}
*我對智能指針不滿意(我以前從未使用過它們,但如果您告訴我如何將其稱為 main,我很樂意使用它們 * 我使用了原始指針,但它仍然顯示錯誤,請幫助 mw
這個想法是合理的,只是執行失敗了。
如果你想要一個工廠函數來返回不同的對象,然后這些對象會以多態的方式運行,這完全沒問題,但有一件重要的事情——你需要返回實際的對象。
您的工廠函數的返回類型為Dragon*
。 這意味着無論您返回什么值,它將是一個指向(某種類型的) Dragon
的指針。 但是,該指針的值可以指向實際上是FireDragon
、 IceDragon
等實例的對象。當您創建此類對象的實例時,指向此類實例的指針可以轉換為適當的返回類型並返回。
但是,在您的情況下,當您創建指向某種龍的指針類型的臨時對象時,您實際上並沒有用實例填充它們。 它們都是用一個未指定的值創建的,然后該值被轉換為一個類型為Dragon*
的未指定值,無法提取它是從哪種類型轉換而來的信息。
所以,為了讓它以通常的方式工作,我們只需要創建一個適當類型的新實例並返回它。 我們不想在轉移所有權時從函數返回原始指針,所以std::unique_ptr
是一個更好的選擇:
std::unique_ptr<Dragon> Dragon::spawn() {
int x = rand() % 5;
/* note - this bit of code doesn't make any sense whatsoever
int y;
if (!if_locked(x)) //is a different function
spawn();
else
y = unlocking(m); //is also a different function
*/
// note that `rand() % 5` will produce values 0 through 4.
switch(x) {
case 0: return std::make_unique<GroundDragon>();
case 1: return std::make_unique<WaterDragon>();
case 2: return std::make_unique<IceDragon>();
case 3: return std::make_unique<FireDragon>();
case 4: return std::make_unique<DarkDragon>();
}
}
現在您根本不需要spawner
功能; 您可以直接使用返回值。
我認為第一個重要的教訓是關於初始化指針。
線GroundDragon* pt;
聲明有一個指向GroundDragon
對象的指針,到目前為止GroundDragon
順利。 然而,這並不能創建一個對象。
打個比方:你創建了一個能夠指向村庄方向的方向標志,但你沒有建造一個實際的村庄來指向它。 而現在,它只是指向某個隨機方向。
由於未初始化, pt
包含一個隨機值,而不是GroundDragon
類型的現有對象的地址。 用它做任何事情很可能會導致不好的事情(特別是未定義的行為)。
為了初始化它,你可以這樣寫GroundDragon* pt = new GroundDragon;
這會在堆上創建一個GroundDragon
類型的對象,並將其地址分配給pt
。
還要注意,每個new
需要delete
以保持內存干凈,只是先發制人地提及這一點。
這是非常重要的知識 - 請務必了解這一點。
我想寫這篇文章是為了向您展示如何使用原始指針,作為 Bartek Banachewicz 答案的補充,他沒有展示初始化原始指針的方法。 但是,他使用智能指針所做的事情顯然是比使用原始指針更好的方法。 但是,我想說您還能夠使用原始指針非常重要。 從長遠來看,確保能夠做到這兩點,並盡可能使用智能指針。
編輯:現在對於代碼的另一部分,
int x = rand() % 5;
int y;
if (!if_locked(x)) //is a function to see if that id is unlocked because i want some dragon to be generated only if you have certain xp so it will call func again until unlocked id is generated
spawn();
else
y = unlocking(m);
首先,請注意調用spawn();
忽略返回值。 這意味着,它根本沒有影響。 你可能想寫的是return spawn();
.
其次, if(!if_locked(x))
在我看來與它應該是相反的。 “如果沒有鎖定”意味着“如果解鎖”,在這種情況下,它不應該再試一次,而是繼續,對吧?
而且,是你用來unlocking
Dragon
成員的Mage m
嗎? 聽起來更像是一個指針,如果你不是特別想要像Dragon
擁有Mage
這樣的關系。
無論如何,我會繼續unlocking
spawn
。 像spawn
這樣的方法說它有利於產卵。 尤其是打印某些東西被解鎖並不是我直覺上理解的生成過程的一部分。 另外,我會以不同的方式命名,因為“解鎖”是一種狀態而不是命令。 像check_for_new_unlocks
或類似的東西一樣,這聽起來像一個命令。 並將其與spawn
分開進行。
另外,請注意,您檢查了狹窄的經驗間隔 - 您確定不會發生間隔從未被觸發的情況,因為角色可能會在間隔內前進而從不調用其間的方法嗎?
此外,我會調用表示某些內容是否以不同方式解鎖的數組。 “解鎖”聽起來像一個命令。 “可用”怎么說?
此外,我發現spawn
的遞歸調用在嘗試x
其他值時可讀性較差,但這是意見。 我想去
int x = rand() % 5;
while(not available[x])
{
x = rand() % 5;
}
不過,根據實際機制,也許這可以做得更聰明。 您可以創建隨機變量,如int x = rand() % total_available();
例如。
請注意,其中很多都是基於意見的。 在這方面,我想向您指出CodeReview - 一旦您的代碼正常工作,您可能希望將其發布在那里,以便人們幫助您在幾個不同方面改進它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.