Funkcje klasy wywoływane przez szablon funkcji

0

Witam.
Czy wywoływanie funkcji klasy przez szablon funkcji jest odpowiednim rozwiązaniem w przypadku gdy kilka klas ma wspólne metody?
Rozwiązanie to w pełni działa prawidłowo, więc pod tym względem nie ma problemu, jednak jestem ciekawy czy można to napisać w lepszy sposób niż podany przeze mnie.

#include <vector>
 
class A{
 
public:
 
	std::vector<int> Calculate_Sizes(){
 
		std::vector<int> Sizes;
 
		//...
 
		return Sizes;
 
	}
 
};
 
class B{
 
public:
 
	std::vector<int> Calculate_Sizes(){
 
		std::vector<int> Sizes;
 
		//...
 
		return Sizes;
 
	}
 
};
 
template <typename T> void Show(std::vector<T> &);
 
int main() {
 
	std::vector<A> a;
	std::vector<B> b;
 
	//...
 
	Show(a);
	Show(b);
 
	return 0;
}
 
template <typename T> void Show(std::vector<T> &Objects){
 
	for (auto &TB_01 : Objects){
 
		std::vector<int> Sizes = TB_01.Calculate_Sizes();
 
		//...
 
	}
 
	//...
 
}
0

ciekawe....

1

Chodzi Ci o polimorfizm? Tworzysz klase bazowa z metoda czysto wirtualna np.: virtual void dupa() = 0; i potem ja nadpisujesz w klasie pochodnej. Tu masz przyklad: http://kacperkolodziej.pl/artykuly/programowanie/261-cpp-funkcje-wirtualne-i-czysto-wirtualne-klasy-abstrakcyjne.html

PS. Jak masz jakies wazne zasoby do zwolnienia w destruktorze klasy pochodnej to Twoj destruktor powinien byc wirtualny.

1
#include <iostream>
#include <vector>
#include <memory>

class Manager
{
public:
	std::vector<int> calculateSizes() { return {}; }

	virtual std::vector<int> calculateSizes1() = 0;
};

class A : public Manager
{
public:
	virtual std::vector<int> calculateSizes1() override final { return { 1, 2 }; }
};

class B : public Manager
{
public:
	virtual std::vector<int> calculateSizes1() override final { return { 3, 4, 5 }; }
};

int main()
{
	std::cout << A().calculateSizes().size() << std::endl;
	std::cout << B().calculateSizes().size() << std::endl;

	auto a = std::make_unique<A>();
	auto b = std::make_unique<B>();
	std::cout << a->calculateSizes1().size() << std::endl;
	std::cout << b->calculateSizes1().size() << std::endl;

	return 0;
}

http://melpon.org/wandbox/permlink/3CVXUQHyEyDjbYjB

jak masz pytania do tego to pytaj

0

Czy override final oznacza, że funkcja nadpisuje funkcję klasy bazowej i nie można jej nadpisać w klasie, która dziedziczyłaby po tej klasie?

Próbowałem użyć polimorfizmu, jednak występował błąd przy próbie przekazania vectora obiektów klasy pochodnej do funkcji przyjmującej vector obiektów klasy bazowej. Najprostszym rozwiązaniem tego problemu wydaje mi się stworzenie vectora zawierającego wskaźniki do elementów vectora, jednak ten sposób wydał mi się niezbyt użyteczny, więc zastąpiłem go funkcją przyjmującą dowolny typ.

#include <iostream>
#include <vector>
#include <memory>

class Manager
{
public:
	std::vector<int> calculateSizes() { return {}; }

	virtual std::vector<int> calculateSizes1() = 0;
};

class A : public Manager
{
public:
	virtual std::vector<int> calculateSizes1() override final { return { 1, 2 }; }
};

class B : public Manager
{
public:
	virtual std::vector<int> calculateSizes1() override final { return { 3, 4, 5 }; }
};

void Show(std::vector<Manager> &);
void Show_Pointer(std::vector<Manager*> &Objects);

int main()
{
	std::cout << A().calculateSizes().size() << std::endl;
	std::cout << B().calculateSizes().size() << std::endl;

	std::vector<A> a;
 	std::vector<B> b;
   
    a.push_back(A());
    a.push_back(A());
  
    //Show(a); - Error

    std::vector<Manager*> manager;
    for (auto &TB_01 : a) manager.push_back(&TB_01);
       
    Show_Pointer(manager);
 
	return 0;
}

void Show(std::vector<Manager> &Objects){
    
	for (auto &TB_01 : Objects) std::cout << TB_01.calculateSizes1().size() << std::endl;
    
}
void Show_Pointer(std::vector<Manager*> &Objects){
    
	for (auto &TB_01 : Objects) std::cout << TB_01->calculateSizes1().size() << std::endl;
    
}

http://melpon.org/wandbox/permlink/jQ5zA5qNHQZazSKl

1

override znaczy, że nadpisujesz virtualną z którejś klas, po których dziedziczysz (jeżeli dodasz override a nie ma czego przeładować to kompilator elegancko Ci o tym powie)

final znaczy to co napisałeś

no tak, aby można było trzymać A i B w 1 wektorze musisz mieć na nie wskaźnik (Manager*) inaczej będziesz miał slicing http://en.wikipedia.org/wiki/Object_slicing

1 użytkowników online, w tym zalogowanych: 0, gości: 1