【问题标题】:why can I pass a reference as an argument to a constructor's pointer parameter?为什么我可以将引用作为参数传递给构造函数的指针参数?
【发布时间】:2014-11-24 17:28:37
【问题描述】:

看看下面代码中派生类的初始化列表。

class city {
    private:
        int id;
        int x;
        int y;
    public:
        int getID(){return id;};
        int getX(){return x;};
        int getY(){return y;};
        city(){
            id =0; x=0; y=0;
        }
        city(int idx, int xx, int yx){
            id = idx;
            x = xx;
            y = yx;
        }
        city(city* cityobj){
            id = cityobj->id;
            x = cityobj->x;
            y = cityobj->y;
        }
};

class city_detail : public city{    
    private:
        city* neighbor;
    public:
        city_detail (city& neighborX, city& cityobj): city(cityobj){ // What???
                                                     /* ^ city(cityobj) and city(&cityobj) both work here */        
            neighbor = &neighborX;
        }
        city* getN(){return neighbor;}
    };

int main(int argc, char*argv[]){

city LA(42, 1, 2);

city PDX(7, 3, 4);

city_detail LA_Detail(PDX, LA);

cout << "LA_Detail.ID: " << LA_Detail.getID() << endl; // works both ways 
cout << "LA_Detail.x: " << LA_Detail.getX() << endl; // works both ways
cout << "LA_Detail.y: " << LA_Detail.getY() << endl; // works both ways

cout << "LA_Detail.NN: " << LA_Detail.getN() << endl; // returns address as it should

city * LA_neighbor = LA_Detail.getN(); 

cout << "LA_neighbor.ID: " << LA_neighbor->getID() << endl; // address is indeed valid
cout << "LA_neighbor.x: " << LA_neighbor->getX() << endl; // address is indeed valid
cout << "LA_neighbor.y: " << LA_neighbor->getY() << endl; // address is indeed valid


return 0;

}

为什么...: city(&amp;cityobj)...: city(cityobj) 都在这里工作?

我认为我不能做后者...: city(cityobj),并且我必须将地址传递给cityobj,因为基类的构造函数需要一个指针。

为什么我没有收到一些编译错误,例如:

cannot convert type city to city *?

显然,我在其他地方无法做到这一点,例如:

void getID(city* aCity){
        cout << "aCityID: " << aCity->getID() << endl;
        cout << "aCityX: " << aCity->getX() << endl;
}

void wrapper(city &aCity){
        getID(&aCity); // I must pass in the address here, else I get an error
}

city Greenway;
wrapper(Greenway); 

【问题讨论】:

  • 因为编译器生成的复制构造函数带有签名city(city const&amp;)
  • 编译器是否为所有类生成带有签名class(class const&amp;)的默认构造函数?您可以为此指出任何文档吗?
  • 是的,除非您定义自己的或 = delete 它或定义移动构造函数(不符合标准的 MSVC 除外)。见stackoverflow.com/q/4943958/21475
  • 啊,所以我什至不需要编写自己的类似复制的构造函数city(city* cityobj)。谢谢你。你知道我写的那种构造函数叫什么吗?还是不是标准做法,没有名字?
  • 嗯,它只是一个普通的(用户定义的)构造函数。在这种情况下,仅使用生成的复制构造函数将是标准做法,但通常您需要定义一个自定义的构造函数(例如,如果您的对象在其构造函数中分配内存)。但是,在这种情况下,定义一个接受指针而不是通常的 const&amp; 的指针仍然不是一个好主意,因为整个语言和标准库都是基于使用标准签名复制对象。

标签: c++ pointers constructor reference initializer-list


【解决方案1】:

它起作用的原因是,当您调用city(cityobj) 时,它使用编译器隐式定义的复制构造函数,而当您调用city(&amp;cityobj) 时,它使用您自己定义的转换构造函数:city(city* cityobj)

你不是想说neighbor(&amp;cityobj)吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-28
    • 2019-08-17
    • 1970-01-01
    • 2017-08-24
    • 1970-01-01
    • 1970-01-01
    • 2012-01-24
    相关资源
    最近更新 更多