将当时错误的代码进行简化后,代码如下:
#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;
}
总结:这个问题暴露自己在基础概念的理解上还存在不足。一言以蔽之,就是“声明”与“定义”的理解没有到位。另外,就是这样使用的场景用得少,之前没有用过,多实践,多发现问题,解决问题,才是成长之道。