Форум программистов, компьютерный форум CyberForum.ru

Базовый класс и производный... - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.92
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
28.09.2010, 17:16     Базовый класс и производный... #1
Есть class A. У него есть функция protected foo();
Есть класс наследник B (class B: public A).
В классе-наследнике B есть функция g(), обращающаяся к foo() базового класса A;

Есть объект класса A:
A objA;

Каким образом можно вызвать функцию g(), для объекта objA???
По сути вопрос в следующим - как через объект базового класса вызвать функцию производного класса для работы с объектом базового класса?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.09.2010, 17:16     Базовый класс и производный...
Посмотрите здесь:

Есть производный класс и базовый; при чём производный использует только ЧАСТЬ ресурсов базового, правильно ли это? C++
C++ базовый и производный класс, в базовом объявлена переменная "protected", она недоступна по имени в производном классе! template <class T> воду мутит!
Есть базовый и производный класс, в базовом определена функция, необходимо её объявить в производном! C++
Создать базовый класс Points и производный от него Line C++
Указатели в базовом классе на базовый класс и производный класс C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
obuhanoe
23 / 21 / 2
Регистрация: 25.08.2010
Сообщений: 93
28.09.2010, 17:45     Базовый класс и производный... #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
 
using namespace std;
 
class A
{
  public:
           A(){};
           ~A(){};
           virtual void g() = 0;
  protected:
           void foo(){cout<<"Hi";}
 
 
};
 
 
class B : public A
{
  public:
          B(){};
          ~B(){};
 
          virtual void g() {foo();};
 
};
 
 
int main()
{
 
   B objb;
   objb.g();
 
 
    return 0;
}
может вот так?
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
28.09.2010, 17:54  [ТС]     Базовый класс и производный... #3
Это вызов из объкта класса B функции класса B.

А как вызвать из
C++
1
2
 A objb;
   objb.g(); //?????
Добавлено через 1 минуту
Мы не можем вызвать foo напрямую.

Добавлено через 18 секунд
Зато можем вызвать g()
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
28.09.2010, 18:03     Базовый класс и производный... #4
Если я вас правильно понял:

C++
1
2
3
4
5
6
7
8
9
10
11
class A
{
   protected:
      void foo() { cout << "foo() called\n";  };
} objA;
 
class B : public class A
{
   public:
      void g(){ cout << "g() called\n\t" };
};
При таких условиях задачи я не вижу её решения: objA не принадлежит классу B и никогда вообще о нём не слышал.

Однако, вариант есть такой:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class A
{
   protected:
      void foo() 
      { 
          cout << "foo() called\n";  
      };
 
   public:
      virtual void g() //обратите внимание на ключевое слово virtual
      {
          cout << "original g() called\n"; 
      };
} objA;
 
class B : public A
{
   public:
      virtual void g() //обратите внимание на ключевое слово virtual
      {
           cout << "g() called\n\t";
           foo(); 
      };
} objB;
 
int main( int argc, char ** argv )
{
   objA.g();                     //Вызовется g() из объекта типа A, как и должно быть
 
   A * ptrA = (A*)(&objB); //берём адрес objB, приводим его к типу указателя на A и
                                    //записываем в ptrA
 
   ptrA->g();                   //вызываем g() из объекта типа B, хотя указатель думает,
                                    //что указывает на объект типа A (см. виртуальные функции)
 
   return 0;
}
Что почитать:
Виртуальные функции, Таблица виртуальных методов

Ну и всё в этом роде.

Другого варианта пока не приходит в голову.

Удачи.
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
28.09.2010, 18:51  [ТС]     Базовый класс и производный... #5
Спасибо огромное. Код пашет, вот только этот способ обхода тоже не идет....
abstarry.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
/*------------------------------------------------------------------------*/
/*                                                                        */
/*  ABSTARRY.H                                                            */
/*                                                                        */
/*  Copyright Borland International 1991, 1992                            */
/*  All Rights Reserved                                                   */
/*                                                                        */
/*------------------------------------------------------------------------*/
 
#if !defined( __ABSTARRY_H )
#define __ABSTARRY_H
 
#if defined( TEMPLATES )
 
    #if !defined( __COLLECT_H )
    #include <Collect.h>
    #endif  // __COLLECT_H
 
    #if !defined( __MEM_H )
    #include <Mem.h>
    #endif  // __MEM_H
 
    #pragma option -Vo-
    #if defined( __BCOPT__ ) && !defined( _ALLOW_po )
    #pragma option -po-
    #endif
 
    _CLASSDEF(ostream)
    _CLASSDEF(ContainerIterator)
    _CLASSDEF(AbstractArray)
    _CLASSDEF(ArrayIterator)
 
    class _CLASSTYPE AbstractArray:  public Collection
    {
 
    public:
 
        friend class ArrayIterator;
 
        virtual Object _FAR & operator []( int loc ) = 0;
 
        virtual int lowerBound() const = 0;
        virtual int upperBound() const = 0;
        virtual sizeType arraySize() const = 0;
 
        virtual void detach( int loc, DeleteType dt = NoDelete ) = 0;
        virtual void detach( Object _FAR &, DeleteType dt = NoDelete ) = 0;
        void destroy( int i )
            {
            detach( i, Delete );
            }
 
        int isEqual( const Object _FAR & ) const;
        void printContentsOn( ostream _FAR & ) const;
 
    };
 
#else   // TEMPLATES
 
    #if !defined( __COLLECT_H )
    #include <Collect.h>
    #endif  // __COLLECT_H
 
    #if !defined( __MEM_H )
    #include <Mem.h>
    #endif  // __MEM_H
 
    #if !defined( __CHECKS_H )
    #include <Checks.h>
    #endif  // __CHECKS_H
 
    #pragma option -Vo-
    #if defined( __BCOPT__ ) && !defined( _ALLOW_po )
    #pragma option -po-
    #endif
 
    _CLASSDEF(ostream)
    _CLASSDEF(ContainerIterator)
    _CLASSDEF(AbstractArray)
    _CLASSDEF(ArrayIterator)
 
    class _CLASSTYPE AbstractArray:  public Collection
    {
 
    public:
 
        AbstractArray( int, int = 0, sizeType = 0 );
        virtual ~AbstractArray();
 
        Object _FAR & operator []( int ) const;
 
        int lowerBound() const
            {
            return lowerbound;
            }
 
        int upperBound() const
            {
            return upperbound;
            }
 
        sizeType arraySize() const;
 
        virtual void detach( Object _FAR &, DeleteType = NoDelete );
        virtual void detach( int, DeleteType = NoDelete );
        void destroy( int i ) { detach( i, DefDelete ); }
        virtual void flush( DeleteType = DefDelete );
 
        virtual int isEqual( const Object _FAR & ) const;
        virtual void printContentsOn( ostream _FAR & ) const;
        //void printContentsOn( ostream _FAR & ) const;
 
        virtual ContainerIterator _FAR & initIterator() const;
 
    protected:
 
        Object _FAR & objectAt( int i ) const
            {
            return *theArray[ zeroBase(i) ];
            }
 
        Object _FAR *ptrAt( int i ) const
            {
            return theArray[ zeroBase(i) ];
            }
 
        int find( const Object _FAR & );
 
        void reallocate( sizeType );
 
        void setData( int, Object _FAR * );
 
        void insertEntry( int );
        void removeEntry( int );
        void squeezeEntry( int );
 
        sizeType delta;
        int lowerbound;
        int upperbound;
        int lastElementIndex;
 
    private:
 
        Object _FAR * _FAR *theArray;
 
        int zeroBase( int loc ) const
            {
            PRECONDITION( loc >= lowerbound && loc <= upperbound );
            return loc - lowerbound;
            }
 
        int boundBase( unsigned loc ) const
            {
            PRECONDITION( loc == UINT_MAX || loc <= upperbound - lowerbound );
            return loc == UINT_MAX ? INT_MAX : loc + lowerbound;
            }
 
        friend class ArrayIterator;
 
    };
 
    inline Object _FAR & AbstractArray::operator [] ( int atIndex ) const
    {
        return objectAt( atIndex );
    }
 
    inline sizeType AbstractArray::arraySize() const
    {
        return sizeType( upperbound - lowerbound + 1 );
    }
 
    class _CLASSTYPE ArrayIterator : public ContainerIterator
    {
 
    public:
 
        ArrayIterator( const AbstractArray _FAR & );
        virtual ~ArrayIterator();
 
        virtual operator int();
        virtual Object _FAR & current();
        virtual Object _FAR & operator ++( int );
        virtual Object _FAR & operator ++();
        virtual void restart();
 
    private:
 
        int currentIndex;
        const AbstractArray _FAR & beingIterated;
 
        void scan();
 
    };
 
#endif  // TEMPLATES
 
#if defined( __BCOPT__ ) && !defined( _ALLOW_po )
#pragma option -po.
#endif
#pragma option -Vo.
 
#endif  // __ABSTARRY_H
array.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*------------------------------------------------------------------------*/
/*                                                                        */
/*  ARRAY.H                                                               */
/*                                                                        */
/*  Copyright Borland International 1991, 1992                            */
/*  All Rights Reserved                                                   */
/*                                                                        */
/*------------------------------------------------------------------------*/
 
#if !defined( __ARRAY_H )
#define __ARRAY_H
 
#if defined( TEMPLATES )
 
    #if !defined( __ARRAYS_H )
    #include <Arrays.h>
    #endif  // __ARRAYS_H
 
    #pragma option -Vo-
    #if defined( __BCOPT__ ) && !defined( _ALLOW_po )
    #pragma option -po-
    #endif
 
    #define Array   BI_TCArrayAsVector
    #define PArray  PBI_TCArrayAsVector
    #define RArray  RBI_TCArrayAsVector
    #define RPArray RPBI_TCArrayAsVector
    #define PCArray PCBI_TCArrayAsVector
    #define RCArray RCBI_TCArrayAsVector
 
    _CLASSDEF( BI_TCArrayAsVector )
 
    #define ArrayIterator   BI_TCArrayAsVectorIterator
    #define PArrayIterator  PBI_TCArrayAsVectorIterator
    #define RArrayIterator  RBI_TCArrayAsVectorIterator
    #define RPArrayIterator RPBI_TCArrayAsVectorIterator
    #define PCArrayIterator PCBI_TCArrayAsVectorIterator
    #define RCArrayIterator RCBI_TCArrayAsVectorIterator
 
    _CLASSDEF( BI_TCArrayAsVectorIterator )
 
#else   // TEMPLATES
 
    #if !defined( __CLSTYPES_H )
    #include <ClsTypes.h>
    #endif  // __CLSTYPES_H
 
    #if !defined( __OBJECT_H )
    #include <Object.h>
    #endif  // __OBJECT_H
 
    #if !defined( __ABSTARRY_H )
    #include <AbstArry.h>
    #endif  // __ABSTARRY_H
 
    #pragma option -Vo-
    #if defined( __BCOPT__ ) && !defined( _ALLOW_po )
    #pragma option -po-
    #endif
 
    _CLASSDEF(Array)
 
    class _CLASSTYPE Array : public AbstractArray
 
    {
 
    public:
 
        Array( int upper, int lower = 0, sizeType aDelta = 0 ) :
            AbstractArray( upper, lower, aDelta )
            {
            }
 
        virtual void add( Object _FAR & );
        void addAt( Object _FAR &, int );
 
        virtual classType isA() const
            {
            return arrayClass;
            }
 
        virtual char _FAR *nameOf() const
            {
            return "Array";
            }
 
    };
 
#endif  // TEMPLATES
 
#if defined( __BCOPT__ ) && !defined( _ALLOW_po )
#pragma option -po.
#endif
#pragma option -Vo.
 
#endif  // __ARRAY_H
MyArray
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//#include <absarray.h>
#include <array.h>
 
 
_CLASSDEF(Array)
 
class _CLASSTYPE MyArray : public Array
{
     public:
      MyArray( int upper, int lower = 0, sizeType aDelta = 0 ) :
        Array( upper, lower, aDelta )
            {
        }
     virtual void removeEntry(int x)
     {
        removeEntry(x);
        //removeEntry
     }
};
То есть наследование Abstarry->Array->MyArray
Есть функция void removeEntry( int ); Она описана как protected.

Есть объект класса array. Из него надо вызвать функцию removeEntry, путем нового порожденного класса....

Добавлено через 1 минуту
Это реально запутано, но как есть(((
Проще класс A и класс B =))))

Добавлено через 1 минуту
Суть в том, что не могу я добавить функцию в public классу Abstarray, как сделали Вы в случае с g()...
У меня она в abstarray protected и называется removeEntry( int )(((((

Добавлено через 3 минуты
Не подумайте, что я псих(((( И что я кайфую от такого кода
это задание такое....
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
28.09.2010, 19:27     Базовый класс и производный... #6
Подождите, давайте сначала всё рассавим на свои места.

Как я понял, у вас есть 3 класса: Abstarray => Array => MyArray.
В MyArray реализована функция removeEntry, которой нет в Array.
Есть объект Array arrayObject. Вам нужно вызвать arrayObject.removeEntry();

Если я вас правильно понял, то это просто дурдом получается, другого слова не подберёшь. Суть наследования - в том, чтобы выделить общие свойства нескольких классов в один базовый класс. То есть если и для объектов MyArray, и для объектов Array должна быть доступна функция removeEntry, её нужно перенести либо в Array, либо в Abstarray.

Теоретически можно попробовать создать указатель на MyArray, присвоить ему адрес arrayObj и из него вызвать removeEntry, но ничего хорошего от такой техники не ждите. Если компилятор вообще вам такое простит.

Понимаете, допустим есть два класса:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
class CExampleBase
{
public:
   int baseN;
   void print(){ cout << baseN; };
};
 
class CExample
{
public:
   int anotherN;
   void printBoth(){ print(); cout << "; " << anotherN; };
};
Технически при создании объекта класса выделяется память только под данные этого объекта, то есть, в случае с CExampleBase - под int CExampleBase::baseN. При вызове функции из класса компилятор скрыто от вас выполняет так называемый thiscall, то есть предаёт функции указатель на объект, с которым ей нужно работать:

C++
1
2
3
4
5
6
7
8
//этот код
CExampleBase obj;
obj.print();
 
//технически выглядит так:
struct TExampleBase{ int baseN; } obj;
print( &obj ); //вызов глобальной функции с передачей адреса банальной структуры,
                  //с которой ей нужно работать
При наследовании выглядит так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
//этот код
CExample obj;
obj.printBoth();
 
//технически выглядит так:
struct TExample
{ 
   int baseN; 
   int anotherN; //при наследовании данные просто выстраиваются
                      //друг за другом, в порядке наследования
} obj;
 
printBoth( &obj );
Теперь представьте себе:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
struct TExampleBase
{ 
   int baseN; 
   //int anotherN; // этой переменной тут нет, она появится только в TExample
} obj;
 
printBoth( (TExample*)(&obj) ); // вызываем функцию из TExample
//которая реализована так:
void printBoth( TExample * object )
{
   cout << object.baseN; //тут всё нормально, в нашем TExampleBase obj есть baseN
   cout << "; " << object.anotherN; // ERROR: попытка обратиться к данным, которых нет в структуре TExampleBase
}
То есть подобные дурилки ни к чему хорошему не приводят. Вы рискуете вылести за пределы структуры и хорошо, если не за пределы виртуального адресного пространства программы, то есть вызвать ошибку сегментации памяти. Видели когда-нибудь сообщение вроде "Error: read of address 0x000000"? Вот вы что-то подобное сделаете. Так что перечитывайте задание, скорее всего, либо оно некорректно поставлено, либо вы его некорректно восприняли.

Удачи.
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
28.09.2010, 19:42  [ТС]     Базовый класс и производный... #7
[quote=talis;990153]Как я понял, у вас есть 3 класса: Abstarray => Array => MyArray.[/quote
Да, верно
В MyArray реализована функция removeEntry, которой нет в Array.
Она не перегружна, но наследуется.


Вот кусок из задания...
10. Выполнить удаление одного элемента массива и снова его распечатать. На основе (показать два способа):
10.1. Нового порожденного от Array класса, в котором делается доступным метод removeEntry из класса AbstractArray. Там он защищен – protected;
Быть может я неправильно понял....Меня ставит в ступор "На основе нового порожденного от Array класса"
Цитата Сообщение от talis Посмотреть сообщение
и для объектов Array должна быть доступна функция removeEntry, её нужно перенести либо в Array, либо в Abstarray.
- Я полностью согласен!

Добавлено через 3 минуты
Цитата Сообщение от talis Посмотреть сообщение
class CExample { public: int anotherN; void printBoth(){ print(); cout << "; " << anotherN; }; };
А почему этот кусок кода должен работать? Быть может стоит написать
C++
1
2
3
4
5
6
class CExample: public CExampleBase
{
public:
   int anotherN;
   void printBoth(){ print(); cout << "; " << anotherN; };
};
???
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
28.09.2010, 20:02     Базовый класс и производный... #8
Цитата Сообщение от GRANDEATH
А почему этот кусок кода должен работать? Быть может стоит написать
Да, вы правы. Опечатка.

Цитата Сообщение от GRANDEATH
В MyArray реализована функция removeEntry, которой нет в Array. Она не перегружна, но наследуется.
Не перегружена - значит не переписана, наследуется - значит она содержится в базовом классе. А в вашей интерпретации она как раз таки не наследуется, а определяется в дочернем классе (MyArray).

Цитата Сообщение от GRANDEATH
10.1. Нового порожденного от Array класса, в котором делается доступным метод removeEntry из класса AbstractArray. Там он защищен – protected;
Как я понял, в классе AbstractArray есть protected void removeEntry(), вызов которого нужно сделать public в MyArray. Тогда:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class CExampleBase
{
    protected:
       void printstr ( char * whatToPrint ) // ваш removeEntry в AbstractArray
       {
           cout << "CExampleBase: " << whatToPrint << endl;
       };
};
 
class CExample : public CExampleBase
{
    public:
      void printstr( char * whatToPrint ) // ваш removeEntry в MyArray
      {
          CExampleBase :: printstr( whatToPrint ); // вызываете removeEntry из пространства имён AbstractArray
      };
};
 
int main( int, char** )
{
    CExample obj;
 
    obj.printstr( "Hello, world!" );
 
    return 0;
}
Тогда всё верно. Не поленитесь, скомпилируйте. Станет яснее.

Удачи.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.09.2010, 21:11     Базовый класс и производный...
Еще ссылки по теме:

C++ Указатель на базовый класс и на производный
C++ Базовый класс цветы, производный тля, условие: тля уничтожает красные цветы
C++ Разработать производный от абстрактного класса Figure класс и класс, производный от производного

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
GRANDEATH
39 / 39 / 1
Регистрация: 13.09.2009
Сообщений: 108
28.09.2010, 21:11  [ТС]     Базовый класс и производный... #9
Спасибо большое. =)
Yandex
Объявления
28.09.2010, 21:11     Базовый класс и производный...
Ответ Создать тему

Метки
классы; с++; полиморфизм
Опции темы

Текущее время: 23:32. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru