Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / наследование виртуальные функции без ссылок / 25 сообщений из 34, страница 1 из 2
26.12.2018, 20:15
    #39753639
Candid2018
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Добрый вечер, хотелось чтобы приведенный код выводил ABC (сейчас выводит AAA)
Без использования ссылок (& и ->) т.е. без адресации руками, в чистом плюсовом стиле.


Код: plaintext
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.
#include <iostream>
#include <vector>

using namespace std;

class A
{
public:
	A(){};
	~A(){};
	virtual void print(){cout<<"A";}
};

class B : public A
{
public:
	B(){};
	~B(){};
	void print(){cout<<"B";}
};

class C : public A
{
public:
	C(){};
	~C(){};
	void print(){cout<<"C";}
};

int main()
{
	vector<A> vA;
	A a;
	B b;
	C c;

	vA.push_back(a);
	vA.push_back(b);
	vA.push_back(c);

	for(auto v:vA)
		v.print();
	return 0;
}
...
Рейтинг: 0 / 0
26.12.2018, 20:40
    #39753649
kolobok0
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Candid2018,

Всё очень просто. По шагам:
1) Найти и понять причину такого поведения
2) Поставить задачу на конкретные изменения
3) Изобразить в коде

Начинайте с первого. Где и почему код так себя ведёт?

(круглый)
ЗЫ
Либо бросайте это всё нафик - это не Ваше.
...
Рейтинг: 0 / 0
26.12.2018, 21:14
    #39753654
Фэйтл Эра
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Candid2018,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	vector<A *> vA;
	A a;
	B b;
	C c;

	vA.push_back(&a);
	vA.push_back(&b);
	vA.push_back(&c);
	
	for (auto v : vA)
		v->print();
...
Рейтинг: 0 / 0
26.12.2018, 21:26
    #39753659
Candid2018
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Фэйтл Эра,

так, конечно, работает, но хотелось бы реализовать без передачи адресов объектов руками. Конструкторы копирования как то переопределить... Чтобы при помещении в контейнер объекты оставались своего типа, а не приводились к базовому.
...
Рейтинг: 0 / 0
26.12.2018, 21:44
    #39753661
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Candid2018Чтобы при помещении в контейнер объекты оставались своего типа, а не приводились к базовому.

Ты сам объявил контейнер объектов базового типа. Так что обломись. Не хочешь связываться с
передачей адресов руками - делай контейнер умных указателей.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
26.12.2018, 21:51
    #39753664
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
...
Рейтинг: 0 / 0
26.12.2018, 21:55
    #39753667
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Candid2018сейчас выводит AAAпоздравляю, ты изобрёл срезку ))

Candid2018Без использования ссылок (& и ->) т.е. без адресации руками, в чистом плюсовом стиле. в чисто явском стиле, ты хотел сказать, да?))
...
Рейтинг: 0 / 0
26.12.2018, 21:58
    #39753668
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Насколько я понимаю СТЛ коллекция должна заранее знать размер помещаемого объекта в коллецию

Размеры B и A разные поэтому при попытке положить B происходит его каст к A и копирование.

Разумеется при этом слетает начиста все таблицы виртуальных методов и ты видишь неверную печать

Возможно так станет понятнее

Код: plaintext
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.
#include <iostream>
#include <vector>

using namespace std;

class A {
public:
  A(){};
  ~A(){};

  A(const A &orig) { std::cout << "A.copy" << std::endl; }

  virtual void print() { cout << "A"; }
};

class B : public A {
public:
  B(){};
  ~B(){};

  B(const B &orig) { std::cout << "B.copy" << std::endl; }

  void print() { cout << "B"; }
};

class C : public A {
public:
  C(){};
  ~C(){};

  C(const C &orig) { std::cout << "C.copy" << std::endl; }
  void print() { cout << "C"; }
};

int main() {
  vector<A> vA;
  A a;
  B b;
  C c;

  vA.push_back(a);
  vA.push_back(b);
  vA.push_back(c);

  for (auto v : vA)
    v.print();
  return 0;
}
...
Рейтинг: 0 / 0
26.12.2018, 21:59
    #39753670
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
--положить B происходит его каст к A и копирование

Оригинальный объект B передается в конструктор копирования A

Никакого каста не происходит
...
Рейтинг: 0 / 0
26.12.2018, 22:06
    #39753673
egorych
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
semen.s.semenпри попытке положить B происходит его каст к A и копирование.происходит не каст, а срезка, то есть данные, характерные для класса B просто теряются, в том и числе и таблица виртуальных функций.
...
Рейтинг: 0 / 0
26.12.2018, 22:11
    #39753676
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Модератор: Перестань задирать людей.
Исправлять свои ошибки хорошо, исправлять чужие тоже хорошо. Обижаться что тебя поправили - очень не хорошо.

White Owl
...
Рейтинг: 0 / 0
26.12.2018, 22:40
    #39753687
Candid2018
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Dimitry Sibiryakov,


спасибо. Данный код решает проблему

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
#include <memory>


        vector<shared_ptr<A>> vA;


	vA.push_back(std::make_shared<A>());
	vA.push_back(std::make_shared<B>());
	vA.push_back(std::make_shared<C>());

	for(auto v:vA)
		v->print();
	return 0;
...
Рейтинг: 0 / 0
26.12.2018, 22:42
    #39753688
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Candid2018Dimitry Sibiryakov,


спасибо. Данный код решает проблему

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
#include <memory>


        vector<shared_ptr<A>> vA;


	vA.push_back(std::make_shared<A>());
	vA.push_back(std::make_shared<B>());
	vA.push_back(std::make_shared<C>());

	for(auto v:vA)
		v->print();
	return 0;



Может лучше std::make_unique ?
...
Рейтинг: 0 / 0
26.12.2018, 22:53
    #39753691
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
semen.s.semenМожет лучше std::make_unique ?
Предлагаю подумать что будет в этом случае с таким кодом:

Код: plaintext
1.
2.
3.
4.
5.
	for(auto v:vA)
		v->print();

	for(auto v:vA)
		v->print();
...
Рейтинг: 0 / 0
26.12.2018, 22:56
    #39753692
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Anatoly Moskovskysemen.s.semenМожет лучше std::make_unique ?
Предлагаю подумать что будет в этом случае с таким кодом:

Код: plaintext
1.
2.
3.
4.
5.
	for(auto v:vA)
		v->print();

	for(auto v:vA)
		v->print();



Да ступил unique_ptr не работает тут

vector<unique_ptr<A>> vA;

vA.push_back(std::make_unique<A>());
vA.push_back(std::make_unique<B>());
vA.push_back(std::make_unique<C>());

for(auto v:vA)
v->print();


Не компилится
...
Рейтинг: 0 / 0
26.12.2018, 22:57
    #39753693
NekZ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Anatoly Moskovskysemen.s.semenМожет лучше std::make_unique ?
Предлагаю подумать что будет в этом случае с таким кодом:

Код: plaintext
1.
2.
3.
4.
5.
	for(auto v:vA)
		v->print();

	for(auto v:vA)
		v->print();


Так Сём Сёмыч не предлагает менять тип в контейнере, только вызывать, make_unique вместо make_shared.
Его право. Это даже скомпилируется и будет работать.
...
Рейтинг: 0 / 0
26.12.2018, 22:57
    #39753694
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
  vector<unique_ptr<A>> vA;

  vA.push_back(std::make_unique<A>());
  vA.push_back(std::make_unique<B>());
  vA.push_back(std::make_unique<C>());

  for (auto &v : vA)
    v->print();

  for (auto &v : vA)
    v->print();




Вот так работает
...
Рейтинг: 0 / 0
26.12.2018, 22:58
    #39753695
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
NekZЭто даже скомпилируется и будет работать.

Не скомпилируется и работать не будет
...
Рейтинг: 0 / 0
26.12.2018, 22:58
    #39753696
NekZ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
semen.s.semenВот так работает
Лучше сделать print() const'ом и итерироваться по const-ссылкам
...
Рейтинг: 0 / 0
26.12.2018, 22:58
    #39753697
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
semen.s.semenНе компилится
А, ну да.
Правда я имел ввиду другое, но компилятор умнее ))

А чтобы unique_ptr применить надо for (auto& v...)
...
Рейтинг: 0 / 0
26.12.2018, 22:59
    #39753698
NekZ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
semen.s.semenNekZЭто даже скомпилируется и будет работать.

Не скомпилируется и работать не будет
Почему?
...
Рейтинг: 0 / 0
26.12.2018, 22:59
    #39753699
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
NekZsemen.s.semenпропущено...


Не скомпилируется и работать не будет
Почему?

error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<A, std::__1::default_delete<A> >'
for (auto v : vA)


Потому
...
Рейтинг: 0 / 0
26.12.2018, 23:03
    #39753700
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
NekZsemen.s.semenВот так работает
Лучше сделать print() const'ом и итерироваться по const-ссылкам

Почему ?
...
Рейтинг: 0 / 0
26.12.2018, 23:04
    #39753701
NekZ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
semen.s.semenNekZпропущено...

Почему?

error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<A, std::__1::default_delete<A> >'
for (auto v : vA)


Потому
Ты не вник в то, что я написал, да? Как обычно, это твоя фича.
Я написал, что не обязательно менять тип в контейнере.
Можно спокойно делать
Код: plaintext
1.
2.
std::vector<std::shared_ptr<A>> v;
v.push_back(std::make_unique<A>());


Т.к. shared_ptr имеет конструктор из unique_ptr&&
...
Рейтинг: 0 / 0
26.12.2018, 23:05
    #39753703
semen.s.semen
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
наследование виртуальные функции без ссылок
NekZsemen.s.semenпропущено...


error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<A, std::__1::default_delete<A> >'
for (auto v : vA)


Потому
Ты не вник в то, что я написал, да? Как обычно, это твоя фича.
Я написал, что не обязательно менять тип в контейнере.
Можно спокойно делать
Код: plaintext
1.
2.
std::vector<std::shared_ptr<A>> v;
v.push_back(std::make_unique<A>());


Т.к. shared_ptr имеет конструктор из unique_ptr&&

А еще он имеет целый int для подсчета ссылок

Прикинь какой оверхед - если вектор огромный
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / наследование виртуальные функции без ссылок / 25 сообщений из 34, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]