Подтвердить что ты не робот

Почему мы можем использовать объявленную переменную в своем конструкторе в С++

Недавно я столкнулся с некоторыми странными ошибками из-за такого кода.

vector<int> a(a);

Почему код выше принят? Когда это необходимо? И как попросить компилятор запретить такое использование? Спасибо.

4b9b3361

Ответ 1

Самый распространенный вариант использования для этого - на самом деле в C, а не на С++ (вы не должны использовать malloc в С++, хотя можете), но в этом случае С++ обратная совместимость:

mytype *p = malloc(sizeof *p);

Предоставив использование выражения p в выражении инициализатора, вы можете передать sizeof *p в malloc, гарантируя, что независимо от размера mytype будет выделен нужный размер. Если вам не разрешалось делать *p, тогда вышеприведенное выражение должно было бы иметь тип mytype дважды, а последующее обслуживание в коде может обновлять один из типов и не обновлять другой.

Ответ 2

Это необычная конструкция, которая действительно используется, но может быть полезна, если класс имеет конструктор, который по какой-либо причине ссылается на какой-либо другой объект, и вызывающий может захотеть зацикливать объект на свою собственную инициализацию.

Вот надуманный пример:

#include <iostream>
using namespace std;

struct PrintAnAddress {
    PrintAnAddress()
        : msg_("")
        , addr_(NULL)
    { }
    PrintAnAddress( char const *msg, PrintAnAddress const &that )
        : msg_( msg )
        , addr_( &that )
    { }
    void operator()( ostream &os ) const {
        cout << msg_ << addr_ << endl;
    }
private:
    char const *msg_;
    PrintAnAddress const *addr_;
};

int main() {
    PrintAnAddress p1;
    PrintAnAddress p2( "p1:", p1 );
    PrintAnAddress p3( "self:", p3 );
    p1(cout);
    p2(cout);
    p3(cout);
}

Когда p2 определен, он настроен на печать адреса p1, но когда p3 определен, он настроен на печать собственного адреса. Если переменная p3 еще не была в области видимости, было бы невозможно ссылаться на нее, чтобы передать ее при ее инициализации. (По крайней мере, не без инструментального класса и каким-то образом получить доступ к указателю this.)

Я уверен, что есть полезные и действительные приложения этой конструкции, но, как я уже сказал, это довольно необычно, поэтому никто не приходит мне в голову в данный момент.