上传指针参考

use*_*536 3 c++ inheritance pointers reference upcasting

我有以下人为的例子(来自实际代码):

template <class T>
class Base {
public:
 Base(int a):x(a) {}
    Base(Base<T> * &other) { }
    virtual ~Base() {}
private:
 int x;
};

template <class T>
class Derived:public Base<T>{
public:
  Derived(int x):Base<T>(x) {}
  Derived(Derived<T>* &other): Base<T>(other) {}

};


int main() {
 Derived<int> *x=new Derived<int>(1);
 Derived<int> y(x);
}
Run Code Online (Sandbox Code Playgroud)

当我尝试编译时,我得到:

1X.cc: In constructor ‘Derived<T>::Derived(Derived<T>*&) [with T = int]’:
1X.cc:27:   instantiated from here
1X.cc:20: error: invalid conversion from ‘Derived<int>*’ to ‘int’
1X.cc:20: error:   initializing argument 1 of ‘Base<T>::Base(int) [with T = int]’
Run Code Online (Sandbox Code Playgroud)

1)显然gcc被构造函数混淆了.如果我从构造函数中删除引用,那么代码将编译.所以我的假设是上传指针引用出了问题.谁能告诉我这里发生了什么?

2)一个稍微不相关的问题.如果我要在构造函数中执行像"删除其他"这样可怕的事情(请跟我一起),当有人向我传递指向堆栈中某些内容的指针时会发生什么?

E.g. Derived<int> x(2);
     Derived<int> y(x);

where 

 Derived(Derived<T>*& other) { delete other;}
Run Code Online (Sandbox Code Playgroud)

如何确保指针合法地指向堆上的某些内容?

Ste*_*sop 10

Base<T>是基本类型Derived<T>,但Base<T>*不是基本类型Derived<T>*.您可以传递派生指针代替基指针,但不能传递派生指针引用来代替基指针引用.

原因是,假设你可以,并假设Base的构造函数在引用中写入一些值:

Base(Base<T> * &other) {
    Base<T> *thing = new Base<T>(12);
    other = thing;
}
Run Code Online (Sandbox Code Playgroud)

你刚刚写了一个指向不是 a的东西Derived<T>的指针Derived<T>.编译器不能让这种情况发生.