如果一个类用同一个函数继承多个类,它如何调用每个继承类的函数而不手动指定每个类?
示例代码如下:
#include <cstdio>
class Interface1
{
public:
virtual ~Interface1() = default;
void foo()
{
printf("%s\n", __PRETTY_FUNCTION__);
}
};
class Interface2
{
public:
virtual ~Interface2() = default;
void foo()
{
printf("%s\n", __PRETTY_FUNCTION__);
}
};
class ObjectWithoutTemplate : public Interface1, Interface2
{
public:
void foo()
{
// How do I write the code to call each InterfaceX's foo() here
// without manually specify each class?
Interface1::foo();
Interface2::foo();
// The desired code looke like
// for each interface in Interfaces {
// interface::foo()
// }
}
};
template <class... Interfaces>
class ObjectWithTemplate : Interfaces...
{
public:
void foo()
{
// It does not compile if the template does not inherit Interface[1|2]
Interface1::foo();
Interface2::foo();
// The desired code looke like
// for each interface in Interfaces {
// interface::foo()
// }
}
};
int main()
{
ObjectWithoutTemplate objWithout;
ObjectWithTemplate<Interface1, Interface2> objWith;
objWithout.foo();
objWith.foo();
return 0;
}
我可以通过手动指定接口来调用接口:
Interface1::foo();
Interface2::foo();
但是对于ObjectWithTemplate
的foo()
,考虑到还会有Interface3
,Interface4
,我如何编写代码来调用每个继承接口的foo()
。
C 17中的折叠表达式有助于:
template <class... Interfaces>
class ObjectWithTemplate : public Interfaces...
{
public:
void foo()
{
(Interfaces::foo(), ...);
}
};
对于C 11/C 14版本,也可以这样做,但更详细。
灵感来源于使用std::tuple为每个可变模板参数生成一个类成员
它不是完美的,因为它增加了二进制大小,但它工作得很干净。
template <class... Interfaces>
class ObjectWithTemplate : public Interfaces...
{
public:
std::tuple<Interfaces...> interfaces;
void foo()
{
// The size becomes 8 * num-of-inherited-classes
printf("sizeof(interfaces)=%zu\n", sizeof(interfaces));
std::apply([&](auto&&... args) {
(static_cast<decltype(args)>(*this).foo(), ...);
},
interfaces);
}
};
假设您不希望任何基重复(并且没有一个基相互继承),您可以这样做;
template <class FirstInterface, class... Interfaces>
class ObjectWithTemplate : public FirstInterface, public ObjectWithTemplate<Interfaces...>
{
public:
void foo()
{
FirstInterface::foo();
ObjectWithTemplate<Interfaces...>::foo();
};
};
// partial specialisation
template<class LastInterface>
class ObjectWithTemplate<LastInterface> : public LastInterface
{
public:
void foo()
{
LastInterface::foo();
};
};
类型的对象
ObjectWithTemplate<Interface1, Interface2> object;
实际上有Interface1
和ObjectWithTemplate
如果重复碱基,或使用两个共享另一个碱基的碱基,例如
ObjectWithTemplate<Interface1, Interface1> object;
ObjectWithTemplate<Interface1, SomethingDerivedFromInterface1> object2;
然后,由于模棱两可,代码将无法编译。
问题内容: 在创建Java程序时,我遇到了一个问题, 子类构造函数通过调用超类的方法抛出错误 代码类似于以下内容: 错误是这样的: 为什么会这样? 问题答案: 超类没有默认的构造函数。因此,您需要将适当的构造函数参数传递给超类: (在和构造函数中,将其作为第一行。)在两种情况下,您都应删除该行。 通常,如果构造函数不是以or 语句开头(并且您只能使用其中之一,而不能同时使用两者),则默认情况下使用
默认任何类都是基础继承自Any(与java中的Object类似),但是我们可以继承其它类。所有的类默认都是不可继承的(final),所以我们只能继承那些明确声明open或者abstract的类: open class Animal(name: String) class Person(name: String, surname: String) : Animal(name) 当我们只有单个构造器时
关于下一个代码,我有一些问题: > 类专业化
我想根据传递给类的模板参数实现一个实现开关: 如果传递的模板类型派生自特定类(此处:Serializable),则创建该类型实例的容器DataElement应派生自SerializableElement,并重载从其继承的两个纯虚拟方法(此处:unloadTo和loadFrom) 然而,如果传递的模板类型不是从Serializable派生的,那么DataElement不应该从Serializable
Jinja 最为强大的地方在于他的模板继承功能,模板继承允许你创建一个基础的骨架模板, 这个模板包含您网站的通用元素,并且定义子模板可以重载的 blocks 。 听起来虽然复杂,但是其实非常初级。理解概念的最好方法就是通过例子。 基础模板 在这个叫做 layout.html 的模板中定义了一个简单的 HTML 文档骨架,你可以 将这个骨架用作一个简单的双栏页面。而子模板负责填充空白的 block:
模板继承可以减少页面内容的重复定义,实现页面内容的重用 典型应用:网站的头部、尾部是一样的,这些内容可以定义在父模板中,子模板不需要重复定义 block标签:在父模板中预留区域,在子模板中填充 extends继承:继承,写在模板文件的第一行 定义父模板base.html { % block block_name % } 这里可以定义默认值 如果不定义默认值,则表示空字符串 { %