多个"level"派生抽象类
Multiple "level" derived abstract classes with
我在C++有问题
- 一个具有公共成员和纯虚函数的抽象基类。这在下面的代码中
A
。 - 具有不同成员和函数的多个派生类。这在下面的代码中
B
并C
。 - 实现虚函数且没有新成员的多个派生类。这在下面的代码中
do_stuff_1
和do_stuff_2
。
到目前为止,我的解决方案是混合模板和抽象类。目标是持有指向抽象类的指针B
或C
并调用do_stuff
。我的问题是
- 我的解决方案好吗?
- 如果没有,有更好的解决方案吗?
- 如果是这样,我应该注意一些陷阱吗?
这是我到目前为止的解决方案
#include <iostream>
#include <memory>
/* base virtual class */
class A {
public:
int a;
A(int a) : a(a) {}
virtual void do_stuff() = 0;
};
/* concrete implementations of do_stuf */
template<class T>
class do_stuff_1 : public T {
public:
using T::T;
void do_stuff(){
std::cout << "do_stuff_1 " << this->a << std::endl;
}
};
template<class T>
class do_stuff_2 : public T {
public:
using T::T;
void do_stuff(){
std::cout << "do_stuff_2 " << this->a + 1 << std::endl;
}
};
/* derived classes from A */
class B : public A {
public:
int b; // one member here but many more in my application
B(int a, int b): A(a), b(b) {}
};
class C : public A {
public:
std::string c; // one member here but many more in my application
C(int a, std::string c): A(a), c(c) {}
};
int main() {
std::unique_ptr<B> x;
x.reset(new do_stuff_1<B>(1, 1));
x->do_stuff();
std::cout << x->b << std::endl;
x.reset(new do_stuff_2<B>(1, 2));
x->do_stuff();
std::cout << x->b << std::endl;
std::unique_ptr<C> z;
z.reset(new do_stuff_1<C>(1, "Yo"));
z->do_stuff();
std::cout << z->c << std::endl;
z.reset(new do_stuff_2<C>(1, "Hello"));
z->do_stuff();
std::cout << z->c << std::endl;
return 0;
}
结果是
do_stuff_1 1
1
do_stuff_2 2
2
do_stuff_1 1
Yo
do_stuff_2 2
Hello
您的解决方案似乎很好。这是一种编译时方法,您可以创建 4 个不同的对象。
主要缺点是:
- 除非实例化模板,否则您将不知道
do_stuff()
代码是否正确。 - 您可以使用不属于基类 A 的类实例化
do_stuff_1
或do_stuff_2
。 您至少应该在模板中使用override
以确保它覆盖虚拟函数。
这里有一个小小的改进来解决这些问题:
template<class T>
class do_stuff_2 : public T {
public:
using T::T;
void do_stuff() override {
static_assert (std::is_base_of<A, T>::value, "T should be derived from A");
std::cout << "do_stuff_2 " << this->a + 1 << std::endl;
}
};
顺便说一句,使用make_unique
会很好。
对我来说
看起来像某种政策,这可能看起来像:
#include <iostream>
#include <memory>
#include <type_traits>
struct AwayToDoTheStuff {
virtual void operator()(int a) = 0;
virtual ~AwayToDoTheStuff() {}
};
/* concrete implementations of do_stuf */
class HowToDoStuff1 : public AwayToDoTheStuff {
public:
void operator()(int a) override {
std::cout << "do_stuff_1 " << a << std::endl;
}
};
class HowToDoStuff2 : public AwayToDoTheStuff {
public:
void operator()(int a) override {
std::cout << "do_stuff_2 " << a + 1 << std::endl;
}
};
/* base virtual class */
template <class HowToDoStuff>
class A {
public:
int a;
A(int a) : a(a) {}
void do_stuff() {
static_assert(std::is_base_of<AwayToDoTheStuff, HowToDoStuff>::value);
HowToDoStuff()(a);
}
};
/* derived classes from A */
template <class HowToDoStuff>
class B : public A<HowToDoStuff> {
public:
int b; // one member here but many more in my application
B(int a, int b): A<HowToDoStuff>(a), b(b) {}
};
template <class HowToDoStuff>
class C : public A<HowToDoStuff> {
public:
std::string c; // one member here but many more in my application
C(int a, std::string c): A<HowToDoStuff>(a), c(c) {}
};
int main() {
B<HowToDoStuff1>(1, 1).do_stuff();
B<HowToDoStuff2>(1, 2).do_stuff();
C<HowToDoStuff1>(1, "Yo").do_stuff();
C<HowToDoStuff2>(1, "Hello").do_stuff();
return 0;
}
但我必须说,这很难判断解决方案是否与如此通用的示例匹配。我希望它能在某些方面帮助你...
编辑:
您似乎需要一个公共基类,以便可以将对象 B 和 C 传递给此类公共函数void f(A &a);
那么我的例子可以这样改编:
/* base virtual class */
class A {
public:
void do_stuff() = 0;
};
template <class HowToDoStuff>
class Policy_A : public A {
public:
int a;
A(int a) : a(a) {}
void do_stuff() override {
static_assert(std::is_base_of<AwayToDoTheStuff, HowToDoStuff>::value);
HowToDoStuff()(a);
}
};
/* derived classes from A */
template <class HowToDoStuff>
class B : public Policy_A<HowToDoStuff> {
public:
int b; // one member here but many more in my application
B(int a, int b): Policy_A<HowToDoStuff>(a), b(b) {}
};
template <class HowToDoStuff>
class C : public Policy_A<HowToDoStuff> {
public:
std::string c; // one member here but many more in my application
C(int a, std::string c): Policy_A<HowToDoStuff>(a), c(c) {}
};
以便可以在不透明的 A 对象上调用do_stuff。
您也可以在创建时传递 HowToDoStuff 对象:
/* base virtual class */
class A {
std::unique_ptr<AwayToDoTheStuff> _stuffer;
public:
int a;
A(std::unique_ptr<AwayToDoTheStuff> stuffer, int a) : _stuffer(std::move(stuffer)), a(a) {}
void do_stuff() {
(*_stuffer)(a);
}
};
/* derived classes from A */
class B : public A {
public:
int b; // one member here but many more in my application
B(std::unique_ptr<AwayToDoTheStuff> &stuffer, int a, int b): A(std::move(stuffer), a), b(b) {}
};
class C : public A {
public:
std::string c; // one member here but many more in my application
C(std::unique_ptr<AwayToDoTheStuff> &stuffer, int a, std::string c): A(std::move(stuffer), a), c(c) {}
};
int main() {
auto stuffer1forB = std::unique_ptr<AwayToDoTheStuff>(new HowToDoStuff1);
auto stuffer2forB = std::unique_ptr<AwayToDoTheStuff>(new HowToDoStuff2);
B(stuffer1forB, 1, 1).do_stuff();
B(stuffer2forB, 1, 2).do_stuff();
auto stuffer1forC = std::unique_ptr<AwayToDoTheStuff>(new HowToDoStuff1);
auto stuffer2forC = std::unique_ptr<AwayToDoTheStuff>(new HowToDoStuff2);
C(stuffer1forC, 1, "Yo").do_stuff();
C(stuffer2forC, 1, "Hello").do_stuff();
return 0;
}
相关文章:
- 如何在从抽象基派生的类中实现相同的方法?
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- 从从该抽象类派生的 Python 对象强制转换C++抽象类C++
- 两个抽象类,派生自同一个基类.如何访问从一个抽象类到另一个抽象类的指针
- 如何防止派生类成为 c++ 中的抽象类?
- 无法实例化抽象类,但类不是抽象/派生方法的参数
- 复制从抽象类派生的对象
- OOP - 抽象类类型,初始化基类和派生类中的变量
- 确保派生的类实现至少是来自抽象类(C )的两种方法之一
- 抽象类的需求是什么?为什么要通过其基类访问派生类方法?在C++
- 派生类使用的抽象类的方法
- 使用从WINRT网格类派生的抽象类时,Casttobase未解决的外部符号错误
- 基类的派生类,用作抽象类
- 多个"level"派生抽象类
- 尝试定义派生自抽象类的类类型的对象时出错
- 从抽象类派生的类的对象应在免费商店中
- C 带有嵌套类的抽象类.派生的类和嵌套类
- 在C++中从抽象类派生的类中没有销毁阶段
- 如果函数是从抽象类派生的,则不能用具体的类指针调用该函数
- 如何实例化从抽象类派生的类