为什么模板化类在初始化列表中识别另一个类的构造函数但在方法体中没有?

时间:2015-01-20 03:21:05

标签: c++

我已经开发了两个类Ptr和Cntr作为Accelerated C ++ Ch.14-6练习的一部分。

  • Ptr类是一个包含指针成员的句柄类,允许用户控制是否复制指针引用的基础对象。
  • Cntr类是一个包含size_t类型成员的类,它是指向给定对象的指针数。

当Ptr尝试调用某些(并非所有)Cntr构造函数和Cntr析构函数时,我收到错误:

  

错误:无法匹配拨打'(Cntr)(std :: size_t *)'

     

错误:无法拨打'(Cntr)()'

我已经通过将构造函数移动到Ptr中的初始化列表来解决了一些问题。但是,在其他情况下,我需要在初始化列表之外调用~Cntr()析构函数。关于为什么它在初始化列表中工作但不在外面工作的指导也会有所帮助。

此代码示例不小,但在 stackoverflow.com 上看到的其他代码限制之内。我的完整ptr.h头文件如下所示:

#ifndef GUARD_Ptr
#define GUARD_Ptr

//Ptr.h header file
#include "vec.h"

using std::size_t;

template <class T> T* clone (const T* tp);
template<> Vec<char>* clone(const Vec<char>* vp);
template <class T> class Ptr;

class Cntr {
public:
    size_t* refptr; // member made public while debugging

    Cntr() : refptr(new size_t(1)) { }
    Cntr(const Cntr& cntptr) : refptr(cntptr.refptr) { ++*refptr; }
    Cntr(size_t* t) : refptr(t) { }

    ~Cntr()
    {
        delete refptr;
    }

    size_t value() {
        return *refptr;
    }

    size_t add() {
        ++*refptr;
        return *refptr;
    }

    size_t subtract() {
        --*refptr;
        return *refptr;
    }   

};


template <class T>
class Ptr {
public:
    // new member to copy the object conditionally when needed
    void make_unique()
    {
       if (cntptr.value() != 1) {
            cntptr.subtract();
            cntptr(new size_t(1));
            p = p? clone(p) : 0; // call the global version of close
       }
    }

    // the rest of the class looks like Ref_handle except for its name
    Ptr() : p(0), cntptr()  { }
    Ptr(T* t): p(t), cntptr() { }
    Ptr(const Ptr<T>& h): p(h.p), cntptr(h.cntptr) { }

    Ptr<T>& operator=(const Ptr<T>& rhs)
    {
        cntptr.add();
        // free the lhs, destroying pointers if appropriate
        if (cntptr.subtract() == 0) {
            ~cntptr();
            delete p;
        }
        // copy in values from the rhs
        cntptr(rhs.cntptr);
        p = rhs.p;
        return *this;
    }

    ~Ptr()
    {
        if (cntptr.subtract() == 0) {
            ~cntptr();
            delete p;
        }
    }

    operator bool() const { return p; }
    T& operator*() const {
        if (p)
            return *p;
        throw std::runtime_error("unbound Ptr");
    }

    T* operator->() const {
        if (p)
            return p;
        throw std::runtime_error("unbound Ptr");
    }

private:
    T* p;
    Cntr cntptr;
};


#endif //GUARD_Ptr

1 个答案:

答案 0 :(得分:1)

您的头文件编译没有任何问题。似乎模板实例化代码存在问题。请确保class T所持有的Ptr符合模板。检查复制构造函数是私有的还是公共的?

请参阅我在http://codepad.org/m7aSJ9pa运行的示例。