模板类的构造函数调用错误问题分析

将当时错误的代码进行简化后,代码如下:

#include <iostream>
#include <string>

using namespace std;

template<class T>
class Test{
    public:
        Test(const string& name) {
            this->m_name = name;
        }   

        void Print() {
            cout << "name" << endl;
        }   

    private:
        string m_name;
        T a;
};

class Student {
public:
    //Student():test("name"){}
    Test<int> test("name");
};


int main(int argc, char ** argv) {
    Student stu;
    return 0;

}
代码1


以上代码暂且称为代码1.

直接贴上当时提示的错误信息为:

test.cpp:25: 错误:expected identifier before string constant
test.cpp:25: 错误:expected ‘,’ or ‘...’ before string constant


一个模板类,想要初始构建的时候,传个参数进行,想到的当然是使用构造函数将name进行传过去。而另一个类Student中使用了Test模板类。并在使用过程中,这样传入Test<int> test("name"),报出上述错误,当时一脸茫然,不知所措。


遇到问题,第一时间自己上网查了下资料,并自己再写了个小示例,查看这样验证是否OK,代码如下:

#include <iostream>
#include <string>

using namespace std;

template<class T>
class Test{
    public:
        Test(const string& name) {
            this->m_name = name;
        }   

        void Print() {
            cout << "name" << endl;
        }   

    private:
        string m_name;
        T a;
};


int main(int argc, char ** argv) {
    Test<int> test("name");
    return 0;

}
代码2


以上代码称为代码2,大家可以自己试一下,使用g++可以成功通过编绎生成可执行文件。问题来了,为什么代码1中使用Test<int> test("name")错误,而代码2中却没有问题呢?


解析:自己对于一些基础概念没有理解到位

1、代码1中,Student中使用Test的时候,是属于类成员声明。声明阶段,只是告诉编绎器,Student类中会有Test<int> test这个类成员,并没有进行内存分配,那怎么可能进行构造函数的调用?

2、代码2中,main函数中使用Test<int> test,表示的是类的定义。定义指的是真正为类的对象分配内存,并构建对象,故这里使用Test<int> test("name")没有问题。

3、如果代码1中,Student类需要使用Test<int> test并在构建的时候将参数传进去得如何修改?可以在Student自身构建的时候,将test的构建函数参数传进去。具体修改见下面代码3部分。


#include <iostream>
#include <string>

using namespace std;

template<class T>
class Test{
    public:
        Test(const string& name) {
            this->m_name = name;
        }   

        void Print() {
            cout << "name" << endl;
        }   

    private:
        string m_name;
        T a;
};

class Student {
public:
    Student():test("name"){}
    Test<int> test;
};


int main(int argc, char ** argv) {
    Student stu;
    return 0;

}


总结:这个问题暴露自己在基础概念的理解上还存在不足。一言以蔽之,就是“声明”与“定义”的理解没有到位。另外,就是这样使用的场景用得少,之前没有用过,多实践,多发现问题,解决问题,才是成长之道。

猜你喜欢

转载自blog.csdn.net/dreamvyps/article/details/73098532