Вызов конструктора по умолчанию из перегруженого конструктора
{
public:
Test():myValue(0), myData(0), myAnotherValue(0){}
Test(int* pointer);
~Test(){};
private:
int myValue;
int myData;
int myAnotherValue;
int* myPointer;
}
В классе определено много переменных, которые инициализируются нулями (или еще какими нибудь значениями).
Есть конструктор по умолчанию, который соответственно делает всю эту работу.
Есть перегруженный конструктор который в добавок проводит инициализацию переменной myPointer. Но при этом еще нужно, чтоб перегруженный конструктор инициализировал остальные переменные, точно так же как конструктор по умолчанию. Самым простым было бы добавить код из конструктора по умолчанию в перегруженный конструктор. Но это плодить лишний код... Можно ли в теле перегруженого конструктора каким либо образом вызвать конструктор по уполчанию, после чего реализовать уже перегруженные операции?
{
//....
Test(int* pointer = NULL);
//....
}
Т.е. если ты будешь вызывать конструктор без параметров (т.е. конструктор по умолчанию)
то это будет аналогично вызову
В общем нужен всего один конструктор. Выглядит это примерно так:
{
//....
Test(int * pointer = NULL);
//....
};
///////////////////////////////////////////
Test::Test(int * pointer) // здесь pointer инициализировать
// не надо
{
// здесь код, который в твоем
// конструкторе по умолчанию
// [color=gray]смотри не изменяй здесь значение pointer'а[/color]
if (pointer)
{
// здесь код твоего
// перегруженного конструктора
}
}
Посмотри еще Скотта Майерса "Эффективное использование С++".Рекомендует делать именно так,т.е. заменить список инициализации вызовом общей инициализирующей функции.Между инициализацией и присваиванием обьектов встроенного типа(если они не
ссылки и не константные) нет никакого функционального отличия.Совет Майерса относится к случаю,когда имеется большое количество членов класса встроенных типов(как у тебя) и необходимо,чтобы все они инициализировались в каждом конструкторе одинаковым образом.
Есть перегруженный конструктор который в добавок проводит инициализацию переменной myPointer. Но при этом еще нужно, чтоб перегруженный конструктор инициализировал остальные переменные, точно так же как конструктор по умолчанию. Самым простым было бы добавить код из конструктора по умолчанию в перегруженный конструктор. Но это плодить лишний код... Можно ли в теле перегруженого конструктора каким либо образом вызвать конструктор по уполчанию, после чего реализовать уже перегруженные операции?
Специально для этого придумали такое ООП-понятие, как наследование. Когда имеется существующий код (в данном случае - конструктор, который инициализирует все нулями), но нужно добавить свой код, не заменяя, а используя предыдущий, нужно пользоваться наследованием.
Вот пример:
class Test
{
public:
Test():myValue(0), myData(0), myAnotherValue(0){}
~Test(){};
private:
int myValue;
int myData;
int myAnotherValue;
}
// Вот мы добавляем сюда int *myPointer:
class TestWithMyPointer : public Test // вид наследования - public,
//protected или private - зависит от целей создания класса
//TestWithMyPointer
{
public:
TestWithMyPointer (int *pointer)
:Test(), myPointer(pointer)
{
};
private:
int *myPointer;
};
Наследование здесь не при чем.
Да, судя по представленному коду, член-данные myPointer имеется в базовом классе, и в производном инициализировать его не представляется возможным.
Но все выглядит так, будто автор привел реальную задачу в упрощенном виде, а на самом-то деле член-данные myPointer был внесен в уже существующий класс, в котором изначально его не было (смотрим конструктор Test()).
Если же я ошибаюсь, и myPointer все-таки существует изначально, это означает опять же использование существующего кода с доработками, т. е. имеет смысл воспользоваться наследованием:
{
...
Test () ...
}
class Derived : public Test
{
public:
Derived (int *ptr)
: Test ()
{
myPointer = ptr;
};
};
1) чтоб не трогать чужой класс,
2) ну просто, чтоб было... влепить куда непопадя.
Оба случая к теме не относятся. :)
Что касается темы, то я рекомендую либо создать специальную приватную функцию инициализации и вызывать её из конструктора, либо не ленится создавать два схожих по списку инициализации конструктора, усли списки эти не велики.
Вариант с Test(int* pointer = NULL) мне не нравится, хотя он тоже работоспособный.
P.S. Я не пью. Просто, я в пути на другом континенте, где нет кириллицы на клаве.
Разрываюсь между вариантами Odissey_ и flat.
В случае с приватной функцией инициализации, ее можно пихать в любой перегруженый конструктор, а в случае с примером flat, придеться делать один большой суперконструктор, где проверять, инициализированы параметры или нет... Это помниться, я так в PHP конструкторы перегружал :)