@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
  • Вопрос задан
  • 3754 просмотра
Решения вопроса 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
Студент программист, второй курс
Дружище, попробуй воспользоваться дружественными функциями, мб поможет решить проблему) мне помогло)
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы