搜索

首页  >  问答  >  正文

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中文网2808 天前383

全部回复(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
  • 取消回复