LINUX.ORG.RU

Вопросы про наследование классов в C++

 , ,


0

1

Привет всем! При выполнении домашнего задания в институте столкнулся с трудностью. Необходимо реализовать класс A и наследовать от него B, C, D. Но мне нужно создать контейнер из обьектов типа B,C,D и вызывать соответствующие методы каждого класса.

Как это реализовать?

1) Сделать виртуальными (в A) все функции из B,C,D или

2) Использовать dynamic_cast или

3) Как-то ещё?

Заранее спасибо за помощь!


Что-то мне подсказывает, что речь идёт об одном единственном виртуальном методе, определенном в родительском классе (А) и переопределённом в наследниках (B, C, D).

yoghurt ★★★★★
()

Но мне нужно создать контейнер из обьектов типа B,C,D

Контейнер из указателей на A, наверное. В плюсовых контейнерах нельзя держать объекты разных типов

Gvidon ★★★★
()

как-то так

class A{
public:
	virtual void foo() = 0;
}

class B : public A{
public:
	void foo();
}

class C : public A{
public:
	void foo();
}

class D : public A{
public:
	void foo();
}

std::vector<A*> list;

for( int i = 0; i < list.size() i++ )
	list[i]->foo();
karmich
()
Ответ на: комментарий от nanoolinux

Да, это как бы само собой. Но лучше список шаредптров )

В 99% случаев, не лучше. Достаточно будет unique_ptr, а ещё лучше взять что-то типа boost::ptr_vector.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

Тип содержимого контейнера в любом случае будет один и тот же, другой вопрос, что интерпретировать это содержимое можно по-разному

Gvidon ★★★★
()

Я бы сделал через Visitor.

E ★★★
()
#include <iostream>
#include <memory>
#include <array>

using std::cout;
using std::endl;

class A {
public:
	virtual ~A() {}
	virtual void foo() = 0;
};

class B : public A {
public:
	virtual void foo() override {
		cout << "B::foo" << endl;
	}
};

class C : public A {
public:
	virtual void foo() override {
		cout << "C::foo" << endl;
	}
};

class D : public A {
public:
	virtual void foo() override {
		cout << "D::foo" << endl;
	}
};

int main(void) {
	std::array<std::unique_ptr<A>, 3> arr = {
		std::unique_ptr<A>(new B),
		std::unique_ptr<A>(new C),
		std::unique_ptr<A>(new D),
	};

	for (auto &i : arr) {
		i->foo();
	}
}

vvviperrr ★★★★★
()
Последнее исправление: vvviperrr (всего исправлений: 1)
Ответ на: комментарий от DarkEld3r

В 99% случаев, когда задачу решают для сдачи зачёта по „С/С++“ ни шаред ни юникью не нужен. Достаточно и по значению хранить.

nanoolinux ★★★★
()
Ответ на: комментарий от karmich

Забыл добавить.

B b;
C c;
D d;

list.push_back(&b);
list.push_back(&c);
list.push_back(&d);

Еще можно вызывать так

for_each(list.begin(),list.end(),mem_fun(&A::foo));
Zodd ★★★★★
()

Если методы одинаковые, то делать виртуальными (типа B::do(), C::do() и тд), если разные, то dynamic_cast (типа B::boobs(), C::cleanup()...)

jeuta ★★★★
()

1) Сделать виртуальными (в A) все функции из B,C,D или

this

2) Использовать dynamic_cast или

оно надо тогда, когда из A нужно вызвать метод, специфичный для B, но неопределённый в C(чистой виртуальной функцией в A этого не сделать, т.к. будет невозможно создать C).

Но мне нужно создать контейнер из обьектов типа B,C,D и вызывать соответствующие методы каждого класса.

ну сделай себе «массив», пергрузи operator[]() (дважды), и прочие операторы. Внутри просто динамический массив указателей *A. Ещё -> тоже, тогда можно будет

array[17]->foo();

emulek
()
Ответ на: комментарий от emulek

Ещё ты забыл operator=(), и конструктор копирования.

Тогда уж и swap в придачу. Какое operator=() без swap?

no-such-file ★★★★★
()

Маловато буста будет.

#include <boost/variant.hpp>

#include <iostream>
#include <vector>

using boost::variant;
using boost::static_visitor;
using boost::apply_visitor;
using std::cout;
using std::vector;

class A {};

class B : public A
{
public:
    void foo() { cout << "B::foo\n"; }
};

class C : public A
{
public:
    void bar() { cout << "C::bar\n"; }
};

class D : public A
{
public:
    void foobar() { cout << "D::foobar\n"; }
};

using object_t = variant<B, C, D>;

struct obj_func_caller : static_visitor<>
{
    void operator()(B & obj) const { obj.foo(); }
    void operator()(C & obj) const { obj.bar(); }
    void operator()(D & obj) const { obj.foobar(); }
};

int main()
{
    vector<object_t> coll = {B{}, C{}, D{}};
    for (auto && elem : coll)
        apply_visitor(obj_func_caller{}, elem);
}

% ./a.out
B::foo
C::bar
D::foobar
alexeiz
()

Спасибо!

Всем большое. Сдал работу.

vmax
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.