搜尋

首頁  >  問答  >  主體

c++中模板类的问题

如下面的这段代码所示,模板类里面有一个模板成员函数,其中有问题的地方我已经标注了,就是注释的那一行。请问为什么要用getValue()这个成员函数啊,如果没有main函数里面的语句,用x.value()是可以编译通过的,但是因为有了main()里面的语句,就必须要用个成员函数才行,这是为什么啊?

#include <iostream>


template<typename T>
class MyClass
{
private:
    T value;
public:
    /*void assign(const MyClass<T>& x)
    {
        value = x.value;
    }*/
    template <typename X>
    void assign(const MyClass<X>& x)
    {
        value = x.value;    //这里有问题,要用getValue()才对。
    }
    const T& getValue() const
    {
        return value;
    }
};

int main()
{
    MyClass<double> d;
    MyClass<int> i;
    d.assign(d);
    d.assign(i);
    return 0;
}

PHP中文网PHP中文网2807 天前382

全部回覆(2)我來回復

  • 伊谢尔伦

    伊谢尔伦2017-04-17 13:28:52

    模板類別在編譯時會根據使用情況實例化成具體的類別。

    例如模板MyClass<T>main中使用了不同的兩個實例,則會實例化成MyClass<double>MyClass<int>兩個類,這兩個類雖然是由同一個模板生成的,但他們是兩個不同的類,沒有友元關係,不能互相存取私有成員。

    template<typename T>
    class MyClass
    {
    private:
        T value;
    public:
        /* ... */
        template <typename X>
        void assign(const MyClass<X>& x)
        {
            value = x.value;  // 1. 当类型 X 与 T 相同时,则为同一个类,可以访问自己的私有成员
                              //    当类型 X 与 T 不同时,则不是同一个类,不能访问对方的私有成员
        }
        const T& getValue() const
        {
            return value;
        }
    };
    
    int main()
    {
        MyClass<double> d;
        MyClass<int> i;
        d.assign(d);  // 2. X 与 T 相同,正常编译运行
        d.assign(i);  // 3. X 与 T 不同,编译报错
        return 0;
    }

    與模板相關的錯誤通常很難在編譯時查出,你可以把上述3的語句註解掉,就能正常編譯運行了,但是如果想使3的語句能編譯運行,就需要透過getValue成員來存取私有成員,使得TX在實例化為不同類型時仍能運作。


    另外,1處的語句使用了operator=進行賦值,則對MyClass<T>模板的類型T提出了一個潛在的要求,即類型T存在operator=參數可由類型X轉化而得。

    回覆
    0
  • 迷茫

    迷茫2017-04-17 13:28:52

    模板類別是在編譯時根據不同的特化產生不同的程式碼的。
    x.value使用了x的私有屬性當然會報錯,成員函數(settergetter)提供介面不是很正常嗎...
    如果沒有main函數裡的東西,編譯器就不會產生MyClass<double>MyClass<int>,只要模板類別裡沒有語法錯誤就行。
    ps.我把value = x.value;改成value = x.vvvvvv;,clang和g++都編譯通過了233

    回覆
    0
  • 取消回覆