1. 程式人生 > >模板類的建構函式呼叫錯誤問題分析

模板類的建構函式呼叫錯誤問題分析

將當時錯誤的程式碼進行簡化後,程式碼如下:

#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;

}


總結:這個問題暴露自己在基礎概念的理解上還存在不足。一言以蔽之,就是“宣告”與“定義”的理解沒有到位。另外,就是這樣使用的場景用得少,之前沒有用過,多實踐,多發現問題,解決問題,才是成長之道。