Про перегрузку конструкторов
От: CEMb  
Дата: 10.11.09 05:14
Оценка:
Видимо, туплю

Есть класс с конструкторами:

class A
{
    // тут стописят внутренних переменных класса
public:
    A();
    A(int i);
    A(char c);
};


при этом
A::A()
{
    // стописят строчек кода по иничиализации внутренних переменных класса
}


...хочется, чтобы в двух других конструкторах была таже самая инициализация, но не хочется писать триста строчек кода.
Как из них выполнить дефолтный конструтор
конструктор
Re: Про перегрузку конструкторов
От: Murom Россия  
Дата: 10.11.09 05:20
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>Видимо, туплю


CEM>Есть класс с конструкторами:


CEM>
CEM>class A
CEM>{
CEM>    // тут стописят внутренних переменных класса
CEM>public:
CEM>    A();
CEM>    A(int i);
CEM>    A(char c);
CEM>};
CEM>


CEM>при этом
CEM>A::A()
CEM>{
CEM>    // стописят строчек кода по иничиализации внутренних переменных класса
CEM>}
CEM>


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

CEM>Как из них выполнить дефолтный конструтор

A::A() { ... }

A::A(int i) : A() { i_ = i; }

A::A(char c) : A() { c_ = c; }
- Eugeny
Re[2]: Про перегрузку конструкторов
От: CEMb  
Дата: 10.11.09 05:23
Оценка:
Здравствуйте, Murom, Вы писали:

Забыл совсем: MS Visual C++ 6.0

M>
M>A::A() { ... }

M>A::A(int i) : A() { i_ = i; }

M>A::A(char c) : A() { c_ = c; }
M>


На это оно ругается

error C2614: 'A' : illegal member initialization: 'A' is not a base or member

Re: Про перегрузку конструкторов
От: Bell Россия  
Дата: 10.11.09 05:37
Оценка:
Здравствуйте, CEMb, Вы писали:

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

CEM>Как из них выполнить дефолтный конструтор

Увы, никак. Можно написать функцию Init, в которую перенести инициализацию, и вызывать ее из конструкторов.
Любите книгу — источник знаний (с) М.Горький
Re: Про перегрузку конструкторов
От: jazzer Россия Skype: enerjazzer
Дата: 10.11.09 05:56
Оценка: +3
Здравствуйте, CEMb, Вы писали:

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

CEM>Как из них выполнить дефолтный конструтор

В текушей версии С++ — никак, жди следующей: http://en.wikipedia.org/wiki/C_0x#Object_construction_improvement
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf

Либо выноси общий код в отдельную функцию и зови ее.
Либо, если там именно инициализация, а не просто код работает по инициализированным данным, сделай базовый класс с этим огромным конструктором и зови его.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Про перегрузку конструкторов
От: MasterZiv СССР  
Дата: 10.11.09 08:06
Оценка:
CEMb wrote:

> M>A::A() { ... }

>
> M>A::A(int i) : A() { i_ = i; }
>
> M>A::A(char c) : A() { c_ = c; }
> M>
>
>
>
> На это оно ругается
>
> error C2614: 'A' : illegal member initialization: 'A' is not a base
> or member

Это, наверное, была шутка. Это вам не Java.


Чтобы сделать такое, тебе нужно сделать отдельную функцию
инициализации, вероятно, приватную, и вызывать
её из каждого конструктора. При этом делать инициализацию
в списке инициализациии не получится.
Если нужно делать инициализацию в списке инициализации,
то придётся написать N функций, для каждого member-а.
Каждая функция должна быть статической и не присваивать в
теле мемберу что-то, а возвращать это что-то в виде значения:

class A
{
....
private:
static int initValFor_i(int i)
{
return i + 10;
}
};

A::A(int i) :
i_(initValFor_i(i))
{}
Posted via RSDN NNTP Server 2.1 beta
Re: Про перегрузку конструкторов
От: Alexander G Украина  
Дата: 10.11.09 09:08
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>Видимо, туплю


CEM>Есть класс с конструкторами:


CEM>
CEM>class A
CEM>{
CEM>    // тут стописят внутренних переменных класса
CEM>public:
CEM>    A();
CEM>    A(int i);
CEM>    A(char c);
CEM>};
CEM>


CEM>при этом
CEM>A::A()
CEM>{
CEM>    // стописят строчек кода по иничиализации внутренних переменных класса
CEM>}
CEM>


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

CEM>Как из них выполнить дефолтный конструтор

если у класса нет паблик предков, нужных конструктору, то


class A_data
{
public:
    // тут стописят внутренних переменных класса
public:
   A_data(); 
   {  
      // стописят строчек кода по иничиализации внутренних переменных класса
   }
};


class A : private A_data
{
public:
    A();
    A(int i);
    A(char c);
};


Если вся инициализация — обнуление, то "стописят строчек кода " не нужны, вместо этого добавить зануление в class A

struct A_data
{
...
}

class A : private A_data
{
public:
    A() : A_data();
    A(int i) : A_data();
    A(char c) : A_data();
};

Но осторожно, на MSVC не работает, если в A_data классы с пользователским конструктором.
Русский военный корабль идёт ко дну!
Re[2]: Про перегрузку конструкторов
От: Кодт Россия  
Дата: 10.11.09 09:28
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Если вся инициализация — обнуление, то "стописят строчек кода " не нужны, вместо этого добавить зануление в class A


Если вся инициализация — обнуление, используйте умные типы членов — auto_value и т.п.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re: Про перегрузку конструкторов
От: x905  
Дата: 11.11.09 05:42
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>Видимо, туплю

...
CEM> // тут стописят внутренних переменных класса
...

это не класс — это помойка
перепроектируй
Re[2]: Про перегрузку конструкторов
От: CEMb  
Дата: 11.11.09 08:17
Оценка:
Здравствуйте, x905, Вы писали:

X>...

CEM>> // тут стописят внутренних переменных класса
X>...

X>это не класс — это помойка

X>перепроектируй

Не, ну всё не совсем так, я просто чтобы было видно хорошо, что ищется.

На самом деле всё немного сложнее. Есть некий класс, который не имеет дефолтного конструктора. Остальных конструкторов у него "много". Причём, на данный момент, на входе конструктора "ведущим" является первый параметр. Он бывает (двух) разных типов. Внутри инициализируется один и тот же объект, но в зависимости от того, с каким классом первого параметра позвали, деинициализация будет разной. За это отвечает внутренний флаг, который в одном конструкторе взводится в TRUE, в другом в FALSE.
Далее. Первым параметром дело не оканчивается, в зависимости от следующих параметров взводятся другие флаги. Получается такая не совсем древесная структура зависимости входных параметров от первых(вторых, третьих).
Т.е. хотелось чего (напишу кодом, русского языка не хватает...)


class A
{
    A(A1 a){…}
    A(A2 a){…}
//    ...
    A(A1 a, B1 b){…}
    A(A1 a, B2 b){…}

    A(A2 a, C1 b){…}
    A(A2 a, C2 b){…}

    A(A2 a, C2 b, D d){…}
};


вот в данном случае, хочется, чтобы 3 и 4 конструкторы делали инициализацию, которую делает первый, а 5 и 6 — 2. А 7 конструктор, делал инициализацию 6-го. Все инициализации отличаются по флагам(не просто обнуление). У меня сейчас схема чуть проще, но она разрастётся и станет сложнее. Плодить стописят родительских классов тоже не хочется.
Re[3]: Про перегрузку конструкторов
От: x905  
Дата: 11.11.09 13:55
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>Здравствуйте, x905, Вы писали:


X>>...

CEM>>> // тут стописят внутренних переменных класса
X>>...

X>>это не класс — это помойка

X>>перепроектируй

CEM>Не, ну всё не совсем так, я просто чтобы было видно хорошо, что ищется.


о ужас !
зачем столько конструкторов ?
сам это пишеш или в "наследство" эти классы свалились?
делай простые классы, а не один "всемогущий" класс — его же поддерживать невозможно будет
и еще раз — перепроектируй класс
Re[4]: Про перегрузку конструкторов
От: CEMb  
Дата: 12.11.09 07:42
Оценка:
Здравствуйте, x905, Вы писали:

X>о ужас !

да -_-

X>зачем столько конструкторов ?

Чтобы легче было в коде писать создание объекта в одну строчку. Ибо замучился каждый раз писать несколько строчек "одинакового" кода.

X>сам это пишеш или в "наследство" эти классы свалились?

Сам.

X>делай простые классы, а не один "всемогущий" класс — его же поддерживать невозможно будет

Он не всемогущий, он под один объект. Который может быть создан разными путями (по секрету всему свету — это надстройка на объект из win32)

X>и еще раз — перепроектируй класс

Попробую.
Re: Про перегрузку конструкторов
От: Erop Россия  
Дата: 12.11.09 11:07
Оценка:
Здравствуйте, CEMb, Вы писали:

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

CEM>Как из них выполнить дефолтный конструтор

Предлагаю тебе такой ход:

1) Пишешь кучу приватных методов вида: initWith( arg1 ); initWith( arg1, afg2 ); initWith( arg1, afg2, arg3 );
В которых помещаешь все свои премудрости с деревом инициализации объекта, в зависимости от типов параметров конструктора.
2) Пишешь явный конструктор копии (или явно его банишь, если надо)
3) И пишешь несколько шаблонных конструкторов вида:
class MyClass {
public:
    template<typename T1, typename T2>
    MyClass( T1 a1, T2 a2 ) { initWith( a1, a2 ); }
};


Ну собственно и наслаждаешься достигнутым эффектом

Если не охота возиться с шаблонами методов, то все те же конструкторы можно и руками быстренько наколотить и макросом каким-нибудь...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Про перегрузку конструкторов
От: Alexander G Украина  
Дата: 12.11.09 11:12
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>(по секрету всему свету — это надстройка на объект из win32)


Тогда очень похоже на то, что на самом деле не особо нужно использовать список инициализации, поэтому общие части конструкторов можно повыносить в отдельные методы.
Русский военный корабль идёт ко дну!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.