簡體   English   中英

如何使用 ZC1C425268E68385D1AB5074C17A4 構造函數將派生的 class object 分配給基本 class 指針

[英]How to assign a derived class object to a base class pointer using a function (not the constructor)

問題總結
I don't know how to create an object of a derived class with the new-operator through a function (not a constructor), and have a base class pointer point to it.

設置
我的項目中有一個抽象基礎 class 和派生 class :

class Base
{
    // stuff
};

class Derived : public Base
{
    //stuff
    //constructor:
    Derived(args);
};

我也有 function 返回Derived的 object。

Derived func(args);

在某個時候,我聲明了一個基本 class 指針

Base* ptr = { nullptr };

我希望它稍后指向Derived的 object。

我想要的是
我想使用func創建一個Derived object ,並能夠在代碼后面通過指針ptr訪問它。

到目前為止我做了什么
我知道使用派生類的構造函數是有效的

ptr = new Derived(args);

或者只是它的默認構造函數,如果它存在的話

ptr = new Derived;

但是,我有充分的理由不能在我的情況下使用構造函數,因為派生的 object 的配置更復雜。 在這種情況下,我想用 function func創建這個 object 。

我知道這個,

ptr = new func(args);

不起作用,因為new需要一個類型。 我怎樣才能實現這樣的行為?

提前感謝您的任何建議和有用的回復。

注意:我使用的是new的,因為我需要在其創建的 scope 之外訪問Derived的 object。

Derived * func(args)
{
  Derived *p = new Derived();
  // do your custom stuff:
  p->x = args->i;
  p->y = 3;

  // return the pointer
  return p;
}

// ...

ptr = func(args);

不要忘記稍后刪除ptr。 為了能夠調用 Derived 的析構函數,稍后使用指向 Base 的指針,您必須將析構函數設為虛擬。

class Base
{
  // ...
  virtual ~Base();
};

func返回一個指針可能是最好的選擇,但如果你不能修改func那么ptr = new Derived(func(args))可能會工作。 這要求Derived具有復制構造函數或移動構造函數。

您可能想考慮將您的 func 編寫為

template<class T, class TA> boost::shared_ptr<T> func(TA args) { return boost::make_shared<T>(args); }

或者

template<class T, class TA> std::shared_ptr<T> func(TA args) { return std::make_shared<T>(args); }

如果您想將其推廣到任何兼容的 class 和參數類型。 您可能還需要 typedef 共享指針以獲得更好的可讀性。 共享指針還將負責 object 的生命周期。

解決方案總結

首先感謝所有回復的人。 建議來得非常快,非常有幫助和啟發。

我不知道這是否違反某些約定,但由於有多種非常不同的解決方案,我想總結一下。 (如果我寧願將此作為問題的編輯,請告訴我)。

所有三個解決方案都應該有效,我現在使用解決方案 2。 但是,在了解有關智能指針的更多信息后,我可能會切換到解決方案 3。

解決方案 1 - AlexDaniel Langr

[回復鏈接]

更改 function func ,使其返回一個指針。

Derived* func(args)
{
    Derived *p = new Derived();
    // do some complicated configuration
    return p;
}

之后,我可以使用 function 直接定義指針ptr

ptr = func(args);

Alex 也對稍后如何刪除ptr做了一些重要的評論。

雖然這很好用,但我選擇不走這條路,因為我想避免更改func的返回值。

解決方案 2 - 由Mestkorn

[回復鏈接]

使用復制構造函數。

這可能是最簡單的解決方案。 通過使用復制構造函數,我可以簡單地編寫

    ptr = new Derived( func(args) );

雖然這需要一個復制/移動構造函數,但它與我項目中的默認復制構造函數完美配合。 我不必實施任何新的東西。 這是我現在在我的代碼中的解決方案。

解決方案 3 - 通過DNT

[回復鏈接]

使用智能指針,更具體地說是shared_ptrstd::shared_ptrboost::shared_ptr 。)這個概念對我來說是全新的。 感謝那!

我將了解更多關於此的信息,並可能切換到此選項,因為它聽起來像是一個更清潔的解決方案。 如果我理解正確的話,相對於其他兩種解決方案的優勢是我不必考慮 memory 泄漏或刪除指針。
一旦我正確地弄清楚了這一點,我將回來並擴展此摘要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM