@frilix
Иногда "творю"

Доступ к полям базового класса?

Как получить доступ к приватным свойствам базового класса из , наследуемого класса.
Мне надо перееопределить базовый конструктор с параметрами в наследуемом классе, но дело в том, что базовый конструктор не принимает в качестве параметров приватные свойтва.
8710ff35db0d4236a8529ec23a292ed9.png
Базовый класс :
#ifndef STROKA_H_INCLUDED
#define STROKA_H_INCLUDED
class Stroka
{
    private:
        char *p_char; // Указатель на строку
        unsigned int size; // Длина строки
    public:
        /* Конструктор без параметров */
        Stroka()
        {
            size = 1;
            p_char = new char[size];
            *p_char = '\0';
            std::cout << "КОНСТРУКТОР  БЕЗ  ПАРАМЕТРОВ" << std::endl;
        }

        /* Конструктор с  параметрами */
        virtual Stroka(const char *st, size_ = 0, p_char_ = NULL)
        {
            size = size_= strlen(st);
            p_char = p_char_ = new char[size];
            strcpy(p_char, st);
            std::cout << "КОНСТРУКТОР  С  ПАРАМЕТРАМИ" << std::endl;
        }

        /* Конструктор с  параметрами*/
        Stroka(const char ch)
        {
            size = 2;
            p_char = new char[size];
            p_char[0] =  ch;
            p_char[1] = '\0';
            std::cout << "КОНСТРУКТОР  С  ПАРАМЕТРАМИ КОТОРЫЙ ПРИНИМАЕТ СИМВОЛ" << std::endl;
        }

        /* Конструктор  копирования */
        Stroka(const Stroka &st)
        {
            size = strlen(st.p_char);
            p_char = new char[size];
            strcpy(p_char, st.p_char);
            std::cout << "КОНСТРУКТОР КОПИРОВАНИЯ" << std::endl;
        }

        /* Вывод  строки на  экран */
        void Print()
        {
            std::cout << "ОТЛАДОЧНАЯ ПЕЧАТЬ\n" << p_char << std::endl;
        }

        /* Перегрузка  присваивания */
        Stroka operator=(const Stroka &st)
        {
            std::cout << "ПЕРЕГРУЗКА ОПЕРАЦИИ" << std::endl;
            delete [] p_char;
            p_char = new char[st.size];

            strcpy(p_char, st.p_char);
            return *this;
        }

        /* Длина  строки */
        unsigned int Size()
        {
            return strlen(p_char);
        }

        /* Деструктор */
        ~Stroka()
        {
            delete [] p_char;
            std::cout << "ДЕСТРУКТОР" << std::endl;
        }

};

#endif // STROKA_H_INCLUDED

Наследуемый класс:
#ifndef STR_INDEF_H_INCLUDED
#define STR_INDEF_H_INCLUDED
class Str_Indef: public Stroka
{

    public:
       Str_Indef():Stroka(){}
       Str_Indef(const char *st):Stroka(st)
       {
            size = strlen(st);
            p_char = new char[size];
            strcpy(p_char, st);
            std::cout << "КОНСТРУКТОР  С  ПАРАМЕТРАМИ" << std::endl;
       }
       Str_Indef(const char ch):Stroka(ch){}
};
#endif // STR_INDEF_H_INCLUDED
  • Вопрос задан
  • 3847 просмотров
Решения вопроса 2
vt4a2h
@vt4a2h Куратор тега C++
Senior software engineer (C++/Qt/boost)
Зачем полям в базовом классе быть private? Сделайте их protected и пользуейтесь в наследниках. А ещё лучше, сделайте в базовом классе конструктор с параметрами.
Вирутальных конструкторов в C++ нет, но есть один паттерн, поищите какой.

class Foo
{
public:
    Foo(int a1, int a2)
        : m_a1(a1)
        , m_a2(a2)
    {}

protected: // Если необходим доступ в потомках, в остальных случаях private
    int m_a1;
    int m_a2;
};

class Bar : public Foo
{
public:
    Bar(int a1, int a2)
        : Foo(a1, a2)
    {}
};


PS
Пользуйтесь #pragma once, деструктор в базовом классе должен быть виртуальным (не всегда... но пока просто делайте всегда), не смешивайте стили, не пишите имена транслитом.
Ответ написан
@DISaccount
В приведенном коде, то что вы делаете в конструкторе наследника Str_Indef(const char *st) - выстрел себе в ногу. Когда Вы сделаете члены с модификатором доступа protected - то автоматом получите утечку памяти. Почему? Потому что вызываете конструктор предка Stroka(st), который уже выделяет память для p_char. Далее снова идет выделение памяти, но уже в наследнике, а то что было выделено предком - затеряется. Про то, что код дублируется и делаете 2 раза одно и то же я вообще молчу.
Дальше. В данном случае Вам вообще не нужен прямой доступ к приватным членам. Все уже делает предок.
Оператор копирования должен возвращать ссылку:
Stroka& operator=(const Stroka &st)
В наследнике - так же необходимо определить оператор копирования и конструктор копирования и не забыть в них вызвать оператор копирования и конструктор копирования предка.
Это беглым взглядом...
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
vusalg
@vusalg
Студент программист, второй курс
Дружище, попробуй воспользоваться дружественными функциями, мб поможет решить проблему) мне помогло)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы