powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / наследование виртуальные функции без ссылок
25 сообщений из 34, страница 1 из 2
наследование виртуальные функции без ссылок
    #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
наследование виртуальные функции без ссылок
    #39753649
kolobok0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Candid2018,

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

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

(круглый)
ЗЫ
Либо бросайте это всё нафик - это не Ваше.
...
Рейтинг: 0 / 0
наследование виртуальные функции без ссылок
    #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
наследование виртуальные функции без ссылок
    #39753659
Candid2018
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Фэйтл Эра,

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

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

Candid2018Без использования ссылок (& и ->) т.е. без адресации руками, в чистом плюсовом стиле. в чисто явском стиле, ты хотел сказать, да?))
...
Рейтинг: 0 / 0
наследование виртуальные функции без ссылок
    #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
наследование виртуальные функции без ссылок
    #39753670
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--положить B происходит его каст к A и копирование

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

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

White Owl
...
Рейтинг: 0 / 0
наследование виртуальные функции без ссылок
    #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
наследование виртуальные функции без ссылок
    #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
наследование виртуальные функции без ссылок
    #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
наследование виртуальные функции без ссылок
    #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
наследование виртуальные функции без ссылок
    #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
наследование виртуальные функции без ссылок
    #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
наследование виртуальные функции без ссылок
    #39753695
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZЭто даже скомпилируется и будет работать.

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

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

Не скомпилируется и работать не будет
Почему?
...
Рейтинг: 0 / 0
наследование виртуальные функции без ссылок
    #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
наследование виртуальные функции без ссылок
    #39753700
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZsemen.s.semenВот так работает
Лучше сделать print() const'ом и итерироваться по const-ссылкам

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


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