warum wird im nachfolgenden Quelltext der Fall
Code: Alles auswählen
Pointer<B> ptr0(...); Pointer<B> ptr1(ptr0);
der Copy-Constructor für einen Pointer gleichen Typs explicit hingeschrieben werden,
sonst erstellt der Compiler (g++ und msc) einen Default-Constructor für den problematischen
Fall.
Hier der Quelltext
Code: Alles auswählen
// #define NONTEMPLATE_CTOR 
#include <iostream>
template<typename T>
class Pointer {
    template<typename U> friend class Pointer;
private:
    T*          _raw;
    unsigned*   _cnt;
public:
    Pointer(void) { }
    Pointer(T* const raw) : _raw(raw), _cnt(new unsigned(1)) { }
#ifdef NONTEMPLATE_CTOR
    Pointer(const Pointer& other) : _raw(other._raw), _cnt(other._cnt) {
        if(_cnt) (*_cnt)++;
    }
#endif
    template<typename U>
    Pointer(const Pointer<U>& other) : _raw(other._raw), _cnt(other._cnt) {
        if(_cnt) (*_cnt)++;
    }
    const T* Raw(void) const { return _raw; }
    unsigned Count(void) const { return *_cnt; }
};
template<class T>
std::ostream& operator<<(std::ostream& stream, const Pointer<T>& ptr) {
    stream << "[" << ptr.Raw() << ", " << ptr.Count() << "]";
    return stream;
}
struct A {
    virtual int Val(void) const { return 10; }
};
struct B : A {
    int Val(void) const { return 20; }
};
int main(int argc, char* argv[]) {
    B* raw = new B();
    Pointer<B> ptr0(raw);
    std::cout << "ptr0 = " << ptr0 << std::endl;
    Pointer<B> ptr1(ptr0);
    std::cout << "ptr0 = " << ptr0 << std::endl;
    std::cout << "ptr1 = " << ptr1 << std::endl;
    Pointer<A> ptr2(ptr0);
    std::cout << "ptr0 = " << ptr0 << std::endl;
    std::cout << "ptr1 = " << ptr1 << std::endl;
    std::cout << "ptr2 = " << ptr2 << std::endl;
    return 0;
}