类模版中无法初始化导致报错——C++学习

踩坑记录,类模版中无法初始化导致报错

原因

关键代码

这里使用了template,用泛型去表达传入参数类型。
主要问题在于 this->pAddress = new T[this->m_Capacity]; 这一句


template<class T>
class MyArray {
public:
    //初始化容量 有参构造
    //explicit标记是构造函数不会做隐式转化
    explicit MyArray(int m_capacity) {
        std::cout << "构造函数执行" << endl;
        this->m_Size = 0;
        this->m_Capacity = m_capacity;
        //主要问题在这
        this->pAddress = new T[this->m_Capacity];
    }

private:
    T *pAddress; //指针指向堆区开辟的地址
    int m_Capacity; //数组容量
    int m_Size;
};

测试代码

MyArray<int> arra1(5); 测试使用int基本类型没有问题

使用泛型为类(非基本类型时报错)



//测试自定义数据类型
class Person {
public:
    // Person() = default;

    Person(const string name, int age)
        : name(name),
          age(age) {
    }

    string name;
    int age;
};


int main(int argc, char *argv[]) {
    // MyArray<int> arra1(5);
    // for (int i = 0; i < 5; ++i) {
    //     //尾插法,插入数据
    //     arra1.Push_Back(i);
    // }
    // print(arra1);
    // cout << "容量:" << arra1.m_capacity() << endl;

    MyArray<Person> arra1(10);
    for (int i = 0; i < 5; ++i) {
        //尾插法,插入数据
        string name = "张三";
        Person p1(name.append(std::to_string(i)), 10 * i);
        arra1.Push_Back(p1);
    }
    print(arra1);
    cout << "容量:" << arra1.m_capacity() << endl;
    cout << "大小:" << arra1.m_size() << endl;
}

错误

从前面可以看到是MyArray构造函数调用出错,说明是Person p1(name.append(std::to_string(i)), 10 * i);调用这一行出现问题。

继续看下面报错,错误指向Person构造函数参数不够!

查看代码,果然没写无参构造函数,当加上Person() = default;就不会出现问题。

In file included from /Users/mac/CLionProjects/stl/main.cpp:3:
/Users/mac/CLionProjects/stl/MyArray.hpp:20:30: error: no matching constructor for initialization of 'Person[]'
        this->pAddress = new T[this->m_Capacity];
                             ^
/Users/mac/CLionProjects/stl/main.cpp:42:21: note: in instantiation of member function 'MyArray<Person>::MyArray' requested here
    MyArray<Person> arra1(10);
                    ^
/Users/mac/CLionProjects/stl/main.cpp:7:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
class Person {
      ^
/Users/mac/CLionProjects/stl/main.cpp:7:7: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were provided
/Users/mac/CLionProjects/stl/main.cpp:11:5: note: candidate constructor not viable: requires 2 arguments, but 0 were provided
    Person(const string name, int age)
    ^
1 error generated.

结论

说明在初始化Tthis->pAddress = new T[this->m_Capacity];的时候是会调用对应类的构造函数的。

添加上构造函数解决问题!

疑问:为什么在c++中初始化数组的时候会调用构造函数?明明初始化是一个空数组!(希望有大佬可以评论区回答一下,我还没找到答案)

附页

C++中若类中没有默认构造函数,如何使用对象数组

### C++ 中 `vector` 初始化报错 `'expected parameter declarator'` 的解决方案 在 C++ 中,如果尝试通过直接赋初值的方式来声明并初始化一个 `std::vector` 成员变量,则可能会遇到编译错误 `'expected parameter declarator'`。这是因为内的语法解析器可能将括号表达式误解为函数声明的一部分。 #### 错误原因分析 当在内部使用如下方式声明 `std::vector` 并试图为其指定初始大小时: ```cpp class A { private: vector<int> aux(5); }; ``` 上述代码会被编译器视为一种函数声明而非对象定义[^1]。具体来说,编译器认为这是声明了一个返回型为 `vector<int>` 的函数 `aux`,该函数接受一个参数 `5`。因此引发了 `'expected parameter declarator'` 编译错误。 --- #### 正确的解决方法 以下是几种可以有效解决问题的方法: ##### 方法一:使用构造函数初始化列表 可以通过的构造函数初始化列表来完成对成员变量 `std::vector` 的初始化操作。例如: ```cpp class A { public: std::vector<int> aux; A() : aux(5) {} // 使用构造函数初始化列表设置向量大小为5 }; ``` 这种方法明确指定了如何初始化 `aux` 向量,并且不会引起任何歧义[^3]。 ##### 方法二:利用默认成员初始化(C++11 及以上版本支持)C++11 开始,允许为中的非静态数据成员提供默认初始化器。这种方式可以直接在体内完成初始化工作而无需借助额外的构造函数逻辑。例如: ```cpp class A { private: std::vector<int> aux = std::vector<int>(5); // 明确表示这是一个具有五个元素的整数型向量 }; ``` 此写法清晰表明我们希望创建的是含有特定数量元素的一个实际的对象实例而不是某种形式上的函数原型[^4]。 ##### 方法三:显式调用标准库模板特化构造函数 还可以采用更冗长但也更加直观的形式——即手动构建一个新的同型的临时对象并将它赋予目标字段名作为其初始状态。像这样实现同样效果但稍显啰嗦些的做法有: ```cpp class A { private: std::vector<int> aux; public: A() { aux = std::vector<int>(5); } }; ``` 不过相比前两种简洁优雅的选择而言,这种做法通常不被推荐除非特殊情况下才考虑使用。 --- ### 总结 为了防止因语法模糊而导致似的编译期问题发生,在现代 C++ 实践当中建议优先选用 **构造函数初始化列表** 或者基于 **default member initializer syntax** 来处理此需求。这两种途径不仅能够提高程序可读性和维护便利程度,同时也完全遵循当前主流开发环境下的最佳实践准则[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

niubility锐

觉得有用的话鼓励鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值