Конструктор по умолчанию для класса с эталонным элементом данных?

У меня есть класс MyClass, в котором мне нужно создать std::array из std::vector в конструкторе по умолчанию. Однако у этого класса есть член данных, который является ссылкой (типа Something), которую также необходимо инициализировать в конструкторе, и я не могу сделать это в конструкторе по умолчанию.

Как мне это решить?

class MyClass{
public:
    MyClass(); //Cannot instantiate s??
    MyClass(Something& s);
    Something& s;
}

MyClass array[10];   // MyClass needs a default constructor but a default 
                     // constructor won't be able to initialize s

person user997112    schedule 05.04.2014    source источник
comment
Можете ли вы дать нам простой пример кода, чтобы проиллюстрировать проблему?   -  person 0x499602D2    schedule 05.04.2014
comment
Но только по описанию я бы сказал, что это классический случай, когда s должно быть Something*, а не Something&...   -  person Massa    schedule 05.04.2014


Ответы (3)


Класс со ссылочным элементом должен установить ссылку в своих конструкторах. В большинстве случаев это означает, что у класса не может быть конструктора по умолчанию. Лучший способ решить проблему — использовать указатель вместо ссылки:

class MyClass{
public:
    MyClass() : s_(0) {}
    MyClass(Something* s) : s_(s) {}
    Something* s_;
}
person Danvil    schedule 05.04.2014
comment
С технической точки зрения он может иметь конструктор по умолчанию (например, если он хранит ссылку на глобальную переменную в s_). Проблема в том, что вам нужно сделать ссылку на экземпляр Something. - person André Caron; 05.04.2014

Как я уже говорил выше, по одному только описанию я бы сказал, что это классический случай, когда s должно быть Something*, а не Something&...

OTOH, это работает отлично, поэтому вам не нужен конструктор по умолчанию, если вы просто инициализируете каждый элемент своего массива:

struct Something { };

struct MyClass {
  MyClass(Something& ss) : s{ss} {}
  Something& s;
};

int main() {
  Something a, b, c, d;
  Something v[10] = { a, b, c, d, a, b, c, d, a, b };
  return 0;
}
person Massa    schedule 05.04.2014
comment
Это потому, что вы использовали инициализатор списка, тогда как у меня нет элементов для добавления в массив для начала :) - person user997112; 05.04.2014
comment
Ну, вы всегда можете сделать MyClass() : s{sx} {}; static Something sx; - person Massa; 05.04.2014

Вы также можете сделать это:

class MyClass{
public:
    MyClass() : s_(0) {}
    MyClass(Something& s) : s_(&s) {}
    Something* s_;
}
person Anas BEKRI    schedule 21.02.2017