Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Конструктор копирования  (Прочитано 29574 раз)
0 Пользователей и 1 Гость смотрят эту тему.
annarv
Гость
« : 10-09-2005 12:54 » 

class base{
private:
int a;
};

class derived:public base{
private:
int b;
derived(const derived &ob){b=ob.b; ?? }
};

Вопрос такой: как можно обратиться к защищенному члену базового класса (a=ob.a)?
Вариант создать функцию член базового класса, получающую значения защищенных членов, исключаеться.
Записан
Alf
Гость
« Ответ #1 : 10-09-2005 14:10 » 

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

Код:
private:
int a;

заменить на

Код:
protected:
int a;

Только после этого производный класс сможет обращаться к члену a базового класса.

P.S. Хотя все вышесказанное верно, на практике гораздо лучше все же сделать конструктор базового класса и вызвать его из конструктора производного. Кроме того, присваивание начальных значений членам класса лучше заменить инициализацией.
Записан
annarv
Гость
« Ответ #2 : 10-09-2005 16:41 » 

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

Конструктор копирования базового класса или обычный? Если можешь приведи конкретный пример, как именно вызвать из производного класса.
Если я првильно понимаю, то нужно добавить конструктор
base::base(int n){a=n}
А что тогда в конструкторе производного класса вызывать, не совсем понятно ?

И насчет инициализации, если можно поясни на конкретном примере.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #3 : 10-09-2005 19:38 » 

Ну примерно в коде это будет выгледеть так
Код:
#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif

// Реализация базового класса
class base{
public:
    base(void);
    base(base *ob);
    void SetA(int as);
protected:
    int a;
};

base::base(void)
{
    SetA(5);
}

base::base(base *ob)
{
    if (ob !=NULL) SetA(ob->a);
    else SetA(5);
}

void base::SetA(int as)
{
    a=as;
}

// Реализация класса derived

class derived:public base{
public:
    derived(derived *ob);
    derived(void);
    void SetB(int bs);
private:
    int b;
};

//Так нужно подключать конструкторы базового класса
derived::derived(void):base()
{
    SetB(5);
}

derived::derived(derived *ob):base((base) ob)
{
    if (ob!=NULL) SetB(ob->b);
    else SetB(5);
}

void derived::SetB(int bs)
{
    b=bs;
}

int main()
{
    derived *dir1=new derived();
    derived dir2(dir1);
    return 0;
}

« Последнее редактирование: 10-09-2005 20:07 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Alf
Гость
« Ответ #4 : 10-09-2005 20:51 » 

Конструктор копирования базового класса или обычный?

Сказанное относится к любому виду конструкторов. Поскольку при создании производного класса создается также и базовый, негоже лишать базовый конструктора.

Кстати, хотя вопрос посвящен конструктору копирования, на самом деле в приведенном примере таковой отсутствует. Если наш класс имеет имя C, то его копирующий конструктор имеет вид:

Код:
class C
{
public:
  ...
  C(const C& c);
  ...
};

В приведенных тобой примерах конструктора с подобной сигнатурой нет, поэтому и конструктора копирования нет тоже.

Если можешь приведи конкретный пример, как именно вызвать из производного класса.

Код:
// базовый класс
class B
{
public:
  // конструктор
  B() { ... }
  ...
}

// производный класс
class D
{
public:
  // конструктор
  D(): B() { ... }
  ...
}

Если я првильно понимаю, то нужно добавить конструктор
base::base(int n){a=n}
А что тогда в конструкторе производного класса вызывать, не совсем понятно ?

Во-первых, если конструктор должен инициализировать переменную-член класса a значением n, лучше сделать это не через присваивание, а через инициализацию:

Код:
base::base(int n): a(n) { }

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

Во-вторых, конструктор производного класса в этом случае будет выглядеть так:

Код:
derived::derived(int n): base(n) { }

И насчет инициализации, если можно поясни на конкретном примере.

См. выше.

P.S. Опять же непонятно, причем тут конструкторы копирования?
Записан
annarv
Гость
« Ответ #5 : 11-09-2005 10:03 » 


Код:
class C
{
public:
  ...
  C(const C& c);
  ...
};

В приведенных тобой примерах конструктора с подобной сигнатурой нет, поэтому и конструктора копирования нет тоже.

P.S. Опять же непонятно, причем тут конструкторы копирования?


В приведенном мной примере помоему есть конструктор копирования в производном классе derived???

class base{
private:
int a;
public:
base(int n):a(n){}
};

class derived:public base{
private:
int b;
public:
derived(int m, int n):base(n),b(m){}

derived(const derived &ob);

};


Насчет обычных конструкторов все понятно, спасибо. Но ответа на вопрос я так и не получила, насчет конструкторов копирования.
Каким образом получить доступ к закрытым членам базового класса в конструкторе копирования производного класса.
Судя по логике обычных конструкторов это должно выглядеть так?
derived::derived(const derived &ob):base(ob.a),b(ob.b){}
Это верно?




Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #6 : 11-09-2005 13:10 » 

Цитата
Насчет обычных конструкторов все понятно, спасибо. Но ответа на вопрос я так и не получила, насчет конструкторов копирования.
Каким образом получить доступ к закрытым членам базового класса в конструкторе копирования производного класса.
Alf писал,
Цитата
Для того, чтобы обратиться  к защищенному члену базового класса, нужно в первую очередь сделать  его защищенным. А именно, конструкцию базового класса

код:
private:
int a;

заменить на

код:
protected:
int a;

Только после этого производный класс сможет обращаться к члену a базового класса.
--
Цитата
Судя по логике обычных конструкторов это должно выглядеть так?
derived::derived(const derived &ob):base(ob.a),b(ob.b){}
Это верно?
В моей программе посмотри,
Код:
derived::derived(derived *ob):base((base) ob)
{
    if (ob!=NULL) SetB(ob->b);
    else SetB(5);
}
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Alf
Гость
« Ответ #7 : 11-09-2005 18:22 » 

В приведенном мной примере помоему есть конструктор копирования в производном классе derived???

Сорвершенно верно, прошу прощения за невнимательность. Это я по поводу базового класса, которому также не повредит конструктор копирования...

Каким образом получить доступ к закрытым членам базового класса в конструкторе копирования производного класса.
Судя по логике обычных конструкторов это должно выглядеть так?
derived::derived(const derived &ob):base(ob.a),b(ob.b){}
Это верно?

Верно. При условии, что в базовом классе переменная a объявлена как protected, а не private. В противном случае производный класс просто не получит доступ к ob.a.
« Последнее редактирование: 11-09-2005 19:08 от Alf » Записан
Human
Гость
« Ответ #8 : 02-05-2006 20:55 » 

Здравствуйте, уважаемые...мне надо добавить в нижеследующую программу конструктор копирования, помогите если кто может, это просто крик души, надо очень срочно...мне кажеться для вас это не составит труда....желательно откомментировать действия...
Код:
class Note{
// определение класса
protected:
// закрытый раздел
struct note{
//объявление структуры
char name[30],soname[30];
//объявление массивов,содержащих имя и фамилию с 30 знаками.
char number[12];
//объявление массива, содержащего номер телефона с 12 знаками
int date[3];} Not[8];
// объявление массива дата, который имеет три числа. И определение структуры //переменной Not состоящей из 8 элементов
note N;
//объявление переменной для сортировки структуры
public :
// открытый раздел
Note(){};
// конструктор класса
~Note(){};
// деструктор класса
void input(void);
// Функция для ввода значений в структуру
void sort(void);
// функция для сортировки структуры
void info(void);
// функция выводит значение по запросу с клавиатуры
};
// закрытие раздела описание класса
void Note::input(void){
// подзаголовок процедуры ввода значение
for (int i=0;i<8;i++){
// цикл 8 раз срабатывает
cout<<"Input name  :";cin>>Not[i].name;
// вывод на экран "Input name" и ввод имени в структуру
cout<<"Input soname  :";cin>>Not[i].soname;
// вывод на экран "Input soname" и ввод фамилии в структуру
cout<<"Input phone number  :";cin>>Not[i].number;
// вывод на экран "Input phone number" и ввод номера телефона в структуру
cout<<"Input d.o.b.  :";cin>>Not[i].date[0]>>Not[i].date[1]>>Not[i].date[2];
// вывод на экран "Input d.o.b." и ввод даты рождения в структуру
}
//закрывает цикл
}
//закрывает функцию
void Note::sort(){
// подзаголовок процедуры сортировки по алфавиту
for (int i=0;i<8;i++)
// цикл 8 раз срабатывает
for (int j=0;j<8;j++)
// цикл 8 раз срабатывает
if (Not[i].name>Not[j].name)
// ищет более старшее имя
{
N=Not[j];
// присваивает временной переменной
Not[i]=Not[j];
// присваивает значение старшего имени
Not[j]=N;
// возвращает значение в структуру
}
//конец поиска
for (int i=0;i<8;i++)
// цикл 8 раз срабатывает
for (int j=0;j<8;j++)
// цикл 8 раз срабатывает
if (Not[i].soname>Not[j].soname)
// ищет старшую фамилию
{
N=Not[j];
// присваивает временной переменной
Not[i]=Not[j];
// присваивает значение старшего фамилии
Not[j]=N;
// возвращает значение в структуру
}
//конец поиска
}
//конец процедуры сортировки. Двойная сортировка необходима для сортировки и имени //по алфавиту и фамилии, вдруг фамилии совпадут.
void Note::info(){
// подзаголовок процедуры вывода информации
bool b=false;
// переменная необходимая для обнаружения существования месяца введенного далее
cout<<"Input number month  :";cin>>int n;
//  вывод на экран Input number month, объявление целочисленной переменной месяца и ввод её с клавиатуры.
for (int i=0;i<8;i++)
// цикл 8 раз срабатывает
if (Not[i].date[1]=n)
// поиск совпадения по месяцу
{
// при совпадение месяца выводит:
cout<<"Name          "<<Not[i].name;
// вывод на экран Name и имени
cout<<"SoName        "<<Not[i].soname;
// вывод на экран SoName и фамилии
cout<<"Phone number  "<<Not[i].number;
// вывод на экран Phone number  и номер телефона
cout<<"Year          "<<Not[i].date[2];
// вывод на экран Year и года рождения
cout<<"Month         "<<Not[i].date[1];
// вывод на экран Month и месяц рождения
cout<<"Day           "<<Not[i].date[0];
// вывод на экран Day и день рождения
b=true;
// если совпадает месяц, то сохраняет, что это произошло 
}
// конец проверки
if (!b) afx_message("persons since ",Not[i].date[1]," months of the birth no");
// если месяц не найден, то выводит сообщение о том, что месяц не найден
}
//конец программы
« Последнее редактирование: 02-05-2006 21:29 от Finch » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 03-05-2006 16:04 » 

Human, посмотри на club.shelek.com статьи по С++ - не так давно и как раз о копировании.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Human
Гость
« Ответ #10 : 13-05-2006 23:04 » 

Пример: MyClass(const MyClass &ob){
a=ob.a;
b=ob.b+1;
}
Вот такой простенький пример конструктора копирования, вопрос состоит в следующем: как я понимаю спецификатор const тут означает что то вроде постоянной ссылки на объект, is it correct? Если нет, то объясните что он означает и можно ли обходиться без него?
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #11 : 14-05-2006 01:02 » 

Фактически ты передаёшь в функцию адрес объекта. Поэтому const гарантирует, что этот объект в данной функции не будет изменён.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Human
Гость
« Ответ #12 : 14-05-2006 11:19 » new

То есть так и есть - "постоянная ссылка на объект"? То есть чтоб она не изменялась, а следовательно не менялся и объект, на который ссылается, а можно обходиться без const?
Записан
nikedeforest
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 14-05-2006 12:04 » 

Нельзя, потому как это будет уже не конструктор копирования.
Записан

ещё один вопрос ...
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #14 : 14-05-2006 14:06 » 

Human, const касается данных, адресуемых ссылкой.
Это лишь средство безопасности и работать можно без него.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Boriska
Помогающий

ua
Offline Offline

« Ответ #15 : 25-03-2015 14:55 » 

Привет
Уважаемая комманда помогите разобраться с конструктором копирования ибо
прочитаное выше не помогло. Студия ругается вот так  'Params' : no appropriate default constructor available

у меня есть некий класс

Код: (C++)
class CGeter
{
        CGeter();
        CGeter(Params netParams, void* p)
        {
                m_netParams = netParams; m_p = p;
        }
        ~CGeter();

public:
        void* Get_P()   { return m_p; }
        Params GetParams() { return m_netParams; }

private:
        void *m_p;
        Params m_netParams;
};


который содержит переменную Params m_netParams
вот такого класса

Код: (C++)
class Params
{
private:

        int m_a;
        int m_b;
        int m_c;
        int m_d;
        int m_f;
       

public:
        Params(int a,int b, int c, int d,int f){ m_a = a; m_b = b; m_c = c; m_d = d; m_f = f;}
       
        Params(const Params &p)
        {
                this->m_a = p.GetA();
                this->m_b = p.GetB();
                this->m_c = p.GetC();
                this->m_d = p.GetD();
                this->m_f = p.GetF();
        }

        Params& operator=(Params p){
                this->m_a = p.GetA();
                this->m_b = p.GetB();
                this->m_c = p.GetC();
                this->m_d = p.GetD();
                this->m_f = p.GetF();
                return *this;
        }

        int GetA()      { return m_a; }
        int GetB()      { return m_b; }
        int GetC()      { return m_c; }
        int GetD()      { return m_d; }
        int GetF()      { return m_f; }

};

Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #16 : 25-03-2015 17:05 » 

У тебя 2 конструктора вместе с деструктором в приватной зоне видимости. Перенеси в публичную.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Boriska
Помогающий

ua
Offline Offline

« Ответ #17 : 25-03-2015 19:05 » 

Поменял, тоже самое

Код: (C++)
class CGeter
{
public://перенес
        CGeter();
        CGeter(Params netParams, void* p)
        {
                m_netParams = netParams; m_p = p;
        }
        ~CGeter();


        void* Get_P()   { return m_p; }
        Params GetParams() { return m_netParams; }

private:
        void *m_p;
        Params m_netParams;
};
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #18 : 25-03-2015 20:48 » 

В таком виде у меня спокойно компилируется, правда не в студии. GCC компилятор.
Код: (C++)
class Params
{
private:

        int m_a;
        int m_b;
        int m_c;
        int m_d;
        int m_f;
       

public:
                Params() {}
        Params(int a,int b, int c, int d,int f){ m_a = a; m_b = b; m_c = c; m_d = d; m_f = f;}
       
        Params(const Params &p)
        {
                this->m_a = p.GetA();
                this->m_b = p.GetB();
                this->m_c = p.GetC();
                this->m_d = p.GetD();
                this->m_f = p.GetF();
        }

        Params& operator=(const Params &p){
                this->m_a = p.GetA();
                this->m_b = p.GetB();
                this->m_c = p.GetC();
                this->m_d = p.GetD();
                this->m_f = p.GetF();
                return *this;
        }

        int GetA() const     { return m_a; }
        int GetB() const     { return m_b; }
        int GetC() const     { return m_c; }
        int GetD() const     { return m_d; }
        int GetF() const     { return m_f; }

};



class CGeter
{
private:
        void *m_p;
        Params m_netParams;
public:
        CGeter() {}
       
        CGeter(const Params &netParams, void* p) {
            m_netParams = netParams;
            m_p = p;
        }
       
        ~CGeter() { }


        void* Get_P()   { return m_p; }
        Params GetParams() { return m_netParams; }

};

int main() {

        CGeter g;
}
« Последнее редактирование: 25-03-2015 20:50 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Boriska
Помогающий

ua
Offline Offline

« Ответ #19 : 26-03-2015 07:35 » 

Спасиб Сравнил Ваш код и мой.
У меня отсутствие конструктора по умолчанию + модификаторов const
Так что студия ни при чем Улыбаюсь Все работает.
« Последнее редактирование: 26-03-2015 07:43 от Boriska » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #20 : 26-03-2015 18:15 » 

И конструктор, и const не важно. У тебя постоение свмой программы не правильно. Для маленьких учебных проектов это не критично. В больших проектах будет вызывать много проблем такое построение.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines