最好在类中的堆栈或堆上进行分配

Meg*_*ron 3 c++ constructor

这更像是一个概念性的问题,但我会提供一个特殊的例子,我对此感到疑惑.如果我有一个具有多个对象作为属性的类,最好是在类中静态分配它们,还是在构造期间动态分配它们?例如,我有以下类(发出不必要的代码)

class OutlinedText
{
protected:
    sf::Text BaseText;
    sf::Text BackgroundText;
}
Run Code Online (Sandbox Code Playgroud)

sf :: Text也是对象.我的问题是,将它们如上所述更好,并按如下方式初始化它们

OutlinedText::OutlinedText(std::string &text, sf::Color MainColor, sf::Color OffsetColor, sf::Font &font, sf::Vector2f Pos, unsigned int BaseFontSize, unsigned int BackFontSize, float Offset)
{
    BaseText = sf::Text(text, font, BaseFontSize);
    BaseText.SetColor(MainColor);
    BackgroundText = sf::Text(text, font, BackFontSize);
    BackgroundText.SetColor(OffsetColor);
}
Run Code Online (Sandbox Code Playgroud)

或者,我应该将它们作为指针并使用new分配它们,如下所示:

BaseText = new sf::Text(text, font, BaseFontSize);
BaseText->SetColor(MainColor);
Run Code Online (Sandbox Code Playgroud)

并在析构函数中使用delete取消分配它们?我知道堆栈分配内存的速度更快,但我认为我正在以现在的方式初始化.那么它是一个案例的事情还是总是比另一个好?我还习惯于以C#的方式做事,所以我很好奇C++的正确方法是什么.如果我有一个根本的误解,请纠正我.

提前致谢

Jam*_*lis 12

只要有可能,您应该避免显式动态分配.动态分配相对昂贵,并且使对象生命周期管理更加困难.

请注意,你的问题是有点误导:在第一种情况下,BaseTextBackgroundText没有在栈上分配的必然.如果OutlinedText它们所属的对象是在堆上分配的,或者是静态变量,那么它们根本就不存在于堆栈中.

我想我现在正以两倍的方式初始化它.

您是:每个成员变量在输入构造函数体之前初始化,然后在构造函数体中,您分配给成员变量,因此它们实际上是"双重初始化".

您可以(并且在大多数情况下应该)使用构造函数的初始化列表来初始化成员变量:

OutlinedText::OutlinedText(std::string& text, 
                           sf::Color MainColor, 
                           sf::Color OffsetColor,
                           sf::Font& font, 
                           sf::Vector2f Pos, 
                           unsigned int BaseFontSize, 
                           unsigned int BackFontSize, 
                           float Offset)
    : BaseText(text, font, BaseFontSize),         // This is the constructor's
      BackgroundText(text, font, BackFontSize)    // initializer list
{
    BaseText.SetColor(MainColor);
    BackgroundText.SetColor(OffsetColor);
}
Run Code Online (Sandbox Code Playgroud)

这样,成员变量只被初始化一次(通过初始化列表中的初始值设定项),而不是两次.

我应该将它们作为指针并使用new分配它们,并在析构函数中使用delete取消它们吗?

不,你不应该写delete在你的C++程序:你应该使用一个智能指针(例如auto_ptr,shared_ptr或者unique_ptr,这取决于你需要什么样的对象生存期),以确保动态分配对象自动销毁.如果你需要存储对象的集合,你应该使用标准库容器中的一个,像vector,map或者set,这也将自动清除您在其中存储的对象.

手动管理动态分配对象的生命周期是繁琐且难以正确的,应该避免.您不仅需要"在析构函数中清理",还需要正确实现(或禁止自动生成)复制构造函数和复制赋值运算符.

C++与C#根本不同,特别是在对象生命周期以及对象如何存在,如何复制以及何时被销毁时.如果你真的想学习这门语言,一定要确保你有一本很好的C++入门书.