Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.79
VLK
194 / 163 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
#1

Наследование класс1 *test = new класс2 - C++

31.07.2013, 21:47. Просмотров 1893. Ответов 54
Метки нет (Все метки)

Кликните здесь для просмотра всего текста
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
#include <iostream> 
 
class BaseClass // Базовый класс
{
public:
BaseClass(): a(0), b(0) { std::cout << "BaseClass constructor.. \n"; }
BaseClass(int rhs_a, int rhs_b): a(rhs_a), b(rhs_b) { std::cout << "BaseClass constructor.. \n"; }
 
void print() const 
{
std::cout << "a: " << a << "\n";
std::cout << "b: " << a << "\n";
}
 
void printBaseClass() const 
{
std::cout << "a: " << a << "\n";
std::cout << "b: " << a << "\n";
}
 
protected:
int a;
int b;
};
 
 
class DerivedClass : public BaseClass // Производный класс от BaseClass
{
public:
DerivedClass(): x(0), y(0), z(0) { std::cout << "DerivedClass constructor.. \n"; }
DerivedClass(int rhs_x, int rhs_y, int rhs_z): x(rhs_x), y(rhs_y), z(rhs_z) { std::cout << "DerivedClass constructor.. \n"; }
 
void print() const 
{
std::cout << "x: " << x << "\n";
std::cout << "y: " << y << "\n";
std::cout << "z: " << z << "\n";
}
 
void printDerivedClass() const 
{
std::cout << "x: " << x << "\n";
std::cout << "y: " << y << "\n";
std::cout << "z: " << z << "\n";
}
 
protected:
int x;
int y;
int z;
};
 
 
int main()
{
setlocale(LC_ALL,"");
 
BaseClass * test = new DerivedClass;
test->print();
test->printBaseClass();
 
 
system("pause");
return 0;
}


Вот небольшая программка, подскажите в чем смысл записи в строчке 58, только не сухое определение записи, что мы создаем объект класса BaseClass и выделяем под него память типа DerivedClass (или как то так), а на пальцах, в чес смысл в чем плюсы и самое главное
чем данная строка отличалась бы от записи BaseClass * test = new BaseClass ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.07.2013, 21:47
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Наследование класс1 *test = new класс2 (C++):

C:\Projects\test\test.cpp|6|error: ISO C++ forbids declaration of 'operator++' with no type [-fpermissive]| - C++
class TUID { public: char Data; TUID (); operator ++ (); };

Заменить наследование классов на наследование интерфейсов - C++
#include &lt;iostream&gt; #include &lt;assert.h&gt; using namespace std; int people_on_base = 100; int vehicles_on_base = 100; double...

Задача на класс2 - Delphi
Помогите до реализовать форму программы Спасибо)

Nginx перенаправляет на http://site.ru/test.ru или http://test.ru/test.ru - Debian Linux
Только, что поставил nginx + php-fpm по этой статье - http://dunmaksim.blogspot.ru/2013/12/nginx-php-fpm.html При попытке зайти на сайт...

Функция file_exists(test/01.ogg) работает, если папка test находится в корневом каталоге моего сервера. - PHP
Столкнулся с интересной проблеммой. Функция file_exists(test/01.ogg) работает, если папка test находится в корневом каталоге моего...

Почему команда «dir>test.txt» работает, а команда «ftp /?>test.txt» — нет? - CMD/BAT
Пробовала без пробелов, что тут еще можно попробовать непонятно Выводит в окно командной строки. Как исправить?

54
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6503 / 3142 / 307
Регистрация: 04.12.2011
Сообщений: 8,669
Записей в блоге: 5
31.07.2013, 22:38 #16
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
#include <iostream> 
 
class BaseClass // Базовый класс
{
public:
BaseClass(): a(0), b(0) { std::cout << "BaseClass constructor.. \n"; }
BaseClass(int rhs_a, int rhs_b): a(rhs_a), b(rhs_b) { std::cout << "BaseClass constructor.. \n"; }
 
void print() const 
{
std::cout << "a: " << a << "\n";
std::cout << "b: " << b << "\n";
}
 
void printBaseClass() const 
{
std::cout << "a: " << a << "\n";
std::cout << "b: " << b << "\n";
}
 
protected:
int a;
int b;
};
 
 
class DerivedClass : public BaseClass // Производный класс от BaseClass
{
public:
DerivedClass(): x(0), y(0), z(0) { std::cout << "DerivedClass constructor.. \n"; }
DerivedClass(int _a, int _b, int rhs_x, int rhs_y, int rhs_z)
: BaseClass(_a, _b), x(rhs_x), y(rhs_y), z(rhs_z) { std::cout << "DerivedClass constructor.. \n"; }
 
void print() const 
{
std::cout << "x: " << x << "\n";
std::cout << "y: " << y << "\n";
std::cout << "z: " << z << "\n";
}
 
void printDerivedClass() const 
{
std::cout << "x: " << x << "\n";
std::cout << "y: " << y << "\n";
std::cout << "z: " << z << "\n";
}
 
protected:
int x;
int y;
int z;
};
 
 
void foo(BaseClass * test){
test->print();
test->printBaseClass();
}
 
int main()
{
setlocale(LC_ALL,"");
 
 
BaseClass * test2 = new BaseClass(6,7);
BaseClass * test = new DerivedClass(1,2,3,4,5);//где-то Вам допустим и этот нужен)
foo(test);
std::cout<<"А теперь горбатый!"<<std::endl;
foo(test2);
system("pause");
return 0;
}
Может какой-то смысл есть и в этом. Но полиморфный вызов не получится. Более того typeinfo тоже покажет что это один и тот же тип. Виртуальная хоть одна, но нужна.
0
VLK
194 / 163 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
31.07.2013, 22:45  [ТС] #17
Я ошибся, ни при такой записи, а только при записи типа BaseClass *test = new DerivedClass

Кликните здесь для просмотра всего текста
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
#include <iostream> 
 
 
class BaseClass // Базовый класс
{
public:
BaseClass() { std::cout << "BaseClass constructor.. \n"; }
virtual ~BaseClass() { std::cout << "BaseClass destructor.. \n"; }
 
 void print() const
{ std::cout << "in BaseClass \n"; }
};
 
 
class DerivedClass : public BaseClass // Производный класс от BaseClass
{
public:
DerivedClass() { std::cout << "DerivedClass constructor.. \n"; }
virtual ~DerivedClass() { std::cout << "DerivedClass destructor.. \n"; }
 
 void print() const
{ std::cout << "in DerivedClass \n"; }
};
 
 
int main()
{
setlocale(LC_ALL,"");
 
BaseClass *test = new DerivedClass;
test->print();
 
system("pause");
return 0;
}


Вот без virtual, мы создаем объект базового класса и соответственно функция print будет вызываться из базового класса

Кликните здесь для просмотра всего текста
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
#include <iostream> 
 
 
class BaseClass // Базовый класс
{
public:
BaseClass() { std::cout << "BaseClass constructor.. \n"; }
virtual ~BaseClass() { std::cout << "BaseClass destructor.. \n"; }
 
virtual void print() const
{ std::cout << "in BaseClass \n"; }
};
 
 
class DerivedClass : public BaseClass // Производный класс от BaseClass
{
public:
DerivedClass() { std::cout << "DerivedClass constructor.. \n"; }
virtual ~DerivedClass() { std::cout << "DerivedClass destructor.. \n"; }
 
virtual void print() const
{ std::cout << "in DerivedClass \n"; }
};
 
 
int main()
{
setlocale(LC_ALL,"");
 
BaseClass *test = new DerivedClass;
test->print();
 
system("pause");
return 0;
}


Тут мы уже используем virtual и уже вызывается функция print из производного класса..


Не знаю как правильно технически задать этот вопрос, но надеюсь вы там поймете, для этого и существуют virtual функции и записи типа BaseClass *test = new DerivedClass

Добавлено через 1 минуту
в этих мною написанных программах, полиморфизм, он заключается в том что один объект, в данном случае test, одновременно является объектом класса BaseClass и объектом класса DerivedClass?
0
Croessmah
Ушел
Эксперт CЭксперт С++
13553 / 7704 / 872
Регистрация: 27.09.2012
Сообщений: 19,006
Записей в блоге: 3
Завершенные тесты: 1
31.07.2013, 22:47 #18
Цитата Сообщение от VLK Посмотреть сообщение
в данном случае test, одновременно является объектом класса BaseClass и объектом класса DerivedClass
Скажем так, что объект производного класса умеет делать все тоже самое, что и объект базового.
0
VLK
194 / 163 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
31.07.2013, 22:51  [ТС] #19
Цитата Сообщение от Croessmah Посмотреть сообщение
Скажем так, что объект производного класса умеет делать все тоже самое, что и объект базового.
Если так по колхозному, то класс имеет 2 вещи, первое это переменные и второе функции (методы), получается что объект производного класса так же получает и переменные базового класса?
0
Fyret
185 / 171 / 13
Регистрация: 30.07.2013
Сообщений: 359
31.07.2013, 22:53 #20
Цитата Сообщение от VLK Посмотреть сообщение
в данном случае test, одновременно является объектом класса BaseClass и объектом класса DerivedClass?
Именно является, это основная фишка открытого наследования.

Добавлено через 1 минуту
Цитата Сообщение от VLK Посмотреть сообщение
что объект производного класса так же получает и переменные базового класса?
Он целиком содержит в себе объект базового класса.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6503 / 3142 / 307
Регистрация: 04.12.2011
Сообщений: 8,669
Записей в блоге: 5
31.07.2013, 22:53 #21
Цитата Сообщение от VLK Посмотреть сообщение
он заключается в том что один объект, в данном случае test, одновременно является объектом класса BaseClass и объектом класса DerivedClass?
Нет. Указателю на базовый можно присвоить и тот и тот, но работать будет именно тот объект на который он действительно указывает. То есть: чем проинициализировали то и будет.
0
VLK
194 / 163 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
31.07.2013, 23:16  [ТС] #22
IGPIGP, Croessmah, Jupiter, блин, все равно не понимаю смысла этого virtual и этой записи ( BaseClass * test = new DerivedClass ), вот без них, просто наследование, я создаю 2 класса Базовый класс (BaseClass) и от него идет Производный класс (DerivedClass), я создаю объект класса DerivedClass, назовем его test и у меня есть доступ ко всем переменным обоих классов и ко всем методам обоих классов, зачем мне это извращение в виде BaseClass * test = new DerivedClass, которое закрывает доступ к методам одного из классов. В чем смысл?
Где ошибка?
0
Croessmah
Ушел
Эксперт CЭксперт С++
13553 / 7704 / 872
Регистрация: 27.09.2012
Сообщений: 19,006
Записей в блоге: 3
Завершенные тесты: 1
31.07.2013, 23:21 #23
Цитата Сообщение от VLK Посмотреть сообщение
блин, все равно не понимаю смысла этого virtual и этой записи
Хоть я и против всякого видео-обучения, но видео лекция:

автор доходчиво объясняет (хоть некоторые моменты и не совсем верны)
1
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6503 / 3142 / 307
Регистрация: 04.12.2011
Сообщений: 8,669
Записей в блоге: 5
31.07.2013, 23:51 #24
Цитата Сообщение от VLK Посмотреть сообщение
зачем мне это извращение в виде BaseClass * test = new DerivedClass, которое закрывает доступ к методам одного из классов. В чем смысл?
Вы же не читаете, что Вам говорят. И с книжками, видимо, та же история. Смотрите, Вам показали, что раскопать: полиморфное наследование. Реакция? Я показал мутный примерчик, где из без полиморфизма нужно использовать указатель на базовый. При передаче аргумента в функцию. Задача же не из простых ответить на вопрос: "Чего я должен захотеть, чтобы это пригодилось?" Пойдите за предложенным вариантом и постарайтесь вникнуть. Пусть у Вас есть массив или контейнер указателей на базовый и дочерние классы и Вы хотите пройти по общим полям (a и b) передавая указатели в функцию, тогда это можно сделать. И полиморфизм тут ни при чем. Хотя главное, это конечно возможность вызова виртуальных методов. То есть, именно при полиморфном наследовании, это обычный приём. Язык позволяет присвоить указателю на базовый, указатель на дочерний без явного приведения. Наоборот, - требуется dynamic_cast...
1
VLK
194 / 163 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
01.08.2013, 13:49  [ТС] #25
Ой.. сколько было написано в этой теме.. а так толком это слово или словосочетание ни кто и не сказал, что ключевое слово virtual служит для перекрытия функции

2 класса Базовый класс (BaseClass) и от него идет Производный класс (DerivedClass), в обоих есть функция-элемент, ну допустим void print()
я создаю BaseClass * test = new DerivedClass, объект test является объектом класса BaseClass и соответственно test->print() будет вызываться из класса BaseClass, что бы при всех тех же условиях вызвать функцию-элемент из класса DerivedClass, мне надо в классе BaseClass, перед функцией-элементом void print() поставить ключевое слово virtual и тогда будет выполнятся функция из класса DerivedClass при том, что объект test у нас является объектом класса BaseClass.

Кликните здесь для просмотра всего текста
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
#include <iostream>
 
class BaseClass // Базовый класс
{
public:
BaseClass() { std::cout << "BaseClass constructor.. \n"; }
virtual ~BaseClass() { std::cout << "BaseClass destructor.. \n"; }
 
virtual void print() const
{ std::cout << "in BaseClass \n"; }
};
  
class DerivedClass : public BaseClass // Производный класс от BaseClass
{
public:
DerivedClass() { std::cout << "DerivedClass constructor.. \n"; }
virtual ~DerivedClass() { std::cout << "DerivedClass destructor.. \n"; }
 
 void print() const
{ std::cout << "in DerivedClass \n"; }
};
  
int main()
{
setlocale(LC_ALL,"");
 
BaseClass *test = new DerivedClass;
test->print();
 
system("pause");
return 0;
}


Вот для наглядности, в данном случае строчка 28 будет обращаться к функции-элементу из строки 19, за счет того, что в строке 9 у нас стоит ключевое слово virtual, если его убрать из 9-й строчки, то тогда будет вызываться функция-элемент из 9-й строчки.

PS я раньше думал что надо во всех местах ставить слово virtual и все функции-элементы делать виртуальными, что то типа такого.

PS2 скажите, если я обе функции print() (строчка 9 и строчка 19) сделаю virtual, тогда будет вызываться метод из строчки 19? Не подумайте что я просто обнаглел и мне тяжело поставить это слово и попробовать, просто если мне не изменяет память, вчера в одном из подобных примеров, с 2-мя virtual функция работала по другому, это мне память изменяет?

PS3 я все правильно понял или опять что то не так?
Спасибо за видео, оно помогло.
0
Schizorb
510 / 462 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
01.08.2013, 13:55 #26
Цитата Сообщение от VLK Посмотреть сообщение
скажите, если я обе функции print() (строчка 9 и строчка 19) сделаю virtual, тогда будет вызываться метод из строчки 19?
В 19 не обязательно. Это будет нужно, если от DerivedClass будет тоже наследоваться новый класс, переопределюящий функцию.
1
VLK
194 / 163 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
01.08.2013, 13:58  [ТС] #27
Цитата Сообщение от Schizorb Посмотреть сообщение
В 19 не обязательно. Это будет нужно, если от DerivedClass будет тоже наследоваться новый класс, переопределюящий функцию.
то, что не обязательно я понял, а вот если я все же пишу в обоих случаях, то какой именно будет вызван метод?
0
Jupiter
Каратель
Эксперт С++
6559 / 3980 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
01.08.2013, 14:00 #28
Цитата Сообщение от VLK Посмотреть сообщение
что бы при всех тех же условиях вызвать функцию-элемент из класса DerivedClass, мне надо в классе BaseClass, перед функцией-элементом void print() поставить ключевое слово virtual и тогда будет выполнятся функция из класса DerivedClass при том, что объект test у нас является объектом класса BaseClass.
нет. объект test у нас является объектом класса DerivedClass

Цитата Сообщение от Schizorb Посмотреть сообщение
В 19 не обязательно. Это будет нужно, если от DerivedClass будет тоже наследоваться новый класс, переопределюящий функцию.
нет. виртуальнай эта функция будет во всех потомках, независимо от того стоит ли virtual в DerivedClass

Цитата Сообщение от VLK Посмотреть сообщение
то, что не обязательно я понял, а вот если я все же пишу в обоих случаях, то какой именно будет вызван метод?
да хоть в обоих, хоть в одном базовом, функция как была виртуальной так ею и останется
2
Schizorb
510 / 462 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
01.08.2013, 14:01 #29
Цитата Сообщение от VLK Посмотреть сообщение
BaseClass * test = new DerivedClass, объект test является объектом класса BaseClass и соответственно test->print() будет вызываться из класса BaseClass
Создается объект класса DerivedClass, в куче. И его адрес присваивается указателю на BaseClass. Указатель на базовый класс может хранить адрес объектов производного класса. Когда вызывается функция через этот объект, то неясно, какую именно нужно вызывать (вернее ясно, будет всегда вызываться из базового). Поэтому и нужно динамическое связывание, с виртуальными функциями.
0
Schizorb
510 / 462 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
01.08.2013, 14:04 #30
Цитата Сообщение от VLK Посмотреть сообщение
то, что не обязательно я понял, а вот если я все же пишу в обоих случаях, то какой именно будет вызван метод?
Разницы не будет, если объявите функцию в производном, как virtual. То есть вызовется функция того класса, объектом которого является данный объект.

Если оставите virtual только в производном - будет работать по-другому.
0
01.08.2013, 14:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.08.2013, 14:04
Привет! Вот еще темы с ответами:

У себя на локале я пишу ссылку test.php?city=1 и в test.php он видет $city==1 - PHP
У себя на локале я пишу ссылку test.php?city=1 и в test.php он видет $city==1 А на хосте не видет. Че это за херня?????

Переименовать ссылку с такой http://test-site.ru/manage на http://test-site.ru/script.php?params=manage - Apache, htaccess
помогите переименовать ссылку с такой http://test-site.ru/manage на http://test-site.ru/script.php?params=manage ...

Реализовать функцию (@COUNT object list test) и (@COUNT-IF test list) - Lisp
Реализовать функции (@COUNT object list test) и (@COUNT-IF test list) , возвращающие количество элементов в списке list, для которых (test...

Test={pero:"lorem"} var t="pero"; console.log(test.t) возможно ли такое ? - JavaScript
Здравствуйте возможно ли такое ? и если да как правильно это написать ? var test={ pero: &quot;lorem 000&quot;, ats: &quot;lorem 123&quot;, kor:...


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru