C++ 初始化作为对象指针容器的成员变量

Posted

技术标签:

【中文标题】C++ 初始化作为对象指针容器的成员变量【英文标题】:C++ Initializing Member Variables that are Containers of Object Pointers 【发布时间】:2022-01-11 07:19:27 【问题描述】:

我很抱歉问这个问题,因为我确信它已经在其他地方得到了回答。我正在尝试在我的类的构造函数中初始化一个对象指针容器。容器是一个数组模板,构造函数的类是A,对象类型是类P。

A.cpp:
    #include 'Array.h'
    #include 'P.h'

    
    A::A()
    Array<P*> ps = ?

P.cpp:
   P::P(string n)
      this->name = n;
   


Array.h:

using namespace std;

template <typename T>
class Array 

    public:
        Array();
                
        ~Array();
        void add(int);
        int get(int index);
        int getSize();
        bool isFull();
        int& operator[] (int);
    
    private:
        int size;
        int* elements;
        static int MAX_ARR = 256;
    
;
template <typename T>
Array<T>::Array()
    elements = new int[MAX_ARR];
    size = 0;

template <typename T>
Array<T>::~Array()
    delete [] elements;

template <typename T>
void Array<T>::add(int t)
    if (size >= MAX_ARR)   return;
    elements[size++] = t;

template <typename T>
int Array<T>::getSize()
    return size;

template <typename T>
bool Array<T>::isFull()
    return size >= MAX_ARR;

template <typename T>
int& Array<T>::operator[](int index)
    if (index < 0 || index >= size) 
        cerr<<"Array index out of bounds"<<endl;
        exit(0);Array
    
    return elements[index];

想知道问号中应该包含什么/如何正确初始化所述成员变量。 P 类很简单,只有一个字符串作为其构造函数的参数。

【问题讨论】:

此问题显示的代码不符合 *** 显示 minimal reproducible example 的要求。因此,这里的任何人都不太可能最终回答这个问题。但最多只能猜测。你需要edit你的问题来展示一个最小的例子,不超过一两页代码(“最小”部分),其他人都可以剪切/粘贴完全如图所示,编译、运行和重现所描述的问题(“可重现”部分,这包括任何辅助信息,如程序的任何输入)。请参阅How to Ask 了解更多信息。 应删除当前设计的Array&lt;P*&gt; ps = ?ps 可能应该是A 类中的类成员变量。尽管您很可能想选择一个更好的名字。在 A 构造函数中,您可能想要调用 ps.add(),但不清楚您希望从哪里获取要添加的数据。 【参考方案1】:

注意:根据您问题的性质,我假设您对 C++ 的一些初始化语法不太熟悉。抱歉,如果不是这种情况并且我误解了您的问题。

如果您只想初始化 ps 变量,那么您可以使用该语法简单地调用默认构造函数:

A::A()

    // This will call the Array default constructor. There is no need for "= <something>"
    Array<P*> ps;

在声明之后,ps 数组已经初始化,您可以立即向其中添加元素。 (但是如果你说它是一个成员变量,那么你甚至不需要那行,ps 默认构造函数将在你进入 A 构造函数体之前被调用。) 如果您来自 Java 或 C# 背景,这可能有点违反直觉,因为在这些语言中,变量将不会使用该语法进行初始化。 但是在 C++ 中,您可以控制变量是在堆上初始化还是在栈上初始化。

堆初始化:Array&lt;P*&gt;* ps = new Array&lt;P*&gt;();

堆栈初始化:Array&lt;P*&gt; ps(); //you can also remove the () and the default constructor will be implicitly called

比较熟悉的栈初始化:Array&lt;P*&gt; ps = Array&lt;P*&gt;() 由于首先创建了一个临时数组,然后将其移动/复制到 ps 变量,因此效率可能有点低。这在技术上比较慢,但是现代编译器通常可以优化掉那个额外的步骤,并简单地就地构造数组。 编辑:在您的情况下,语法不可用,因为您在 Array 类中定义了一个自定义析构函数no copy and move assignment operators will be auto-generated。您需要先手动实现它们。

如果您想知道如何直接使用其内容构造数组,那么我建议您查看std::initializer_list。通过向 Array 类添加支持 initializer_list 的构造函数,您就可以使用以下语法。

A::A()
    // Assuming your string object can be constructed in such way.
    : ps(new P(string("foo")), new P(string("bar")))

【讨论】:

以上是关于C++ 初始化作为对象指针容器的成员变量的主要内容,如果未能解决你的问题,请参考以下文章

C++面向对象-static、const

C++指向对象成员的指针

C++指向对象成员的指针

C++面向对象:静态成员和静态成员函数

C++类和对象下

[C++] 智能指针的引用计数如何实现?—— 所有该类的对象共享静态类成员变量