gpt4 book ai didi

c++ - 无需继承直接访问类接口(interface)中成员的成员

转载 作者:太空狗 更新时间:2023-10-29 21:11:02 25 4
gpt4 key购买 nike

我面临的问题是,在我的应用程序中,类成员在构造函数中的初始化顺序很重要。因此,我需要使用笨拙的语法来获得我想要的行为。

这应该概述了我的问题(见下面的代码):我想要我的 class Widget包括 class WidgetSignals 的界面从用户的角度来看。我不能使用继承,因为这需要我初始化继承的 WidgetSignals成员(member)前elementsWidget应该用来初始化 WidgetSignals .

template<typename... Elems>
class WidgetSignals
{
WidgetSignals(const std::tuple<Elems...> elems)
: // initialize members using elems
{}
// members ...
};

template<typename... Elems>
class Widget : public WidgetSignals<Elems...>
{
std::tuple<Elems...> elements;

Widget(vec4 quad)
: WidgetSignals<Elems...>(elements) // uh-oh! elements are not initialized yet!
, elements(initalizeElements(quad))
};

这是我以前对这个问题的解决方案:

使用中介助手类:

template<typename... Elems>
class Widget : public WidgetSignals<Elems...>
{
std::tuple<Elems...> elements;

struct Data
{
Data(vec4 quad)
: elems(initializeElements(quad)) // initialize elements here
{}
std::tuple<Elems...> elems;
};
Widget(Data data)
: WidgetSignals<Elems...>(data.elems) // bingo!
, elements(data.elems)
{}
};

封装WidgetSignals并公开对 WidgetSignals 的引用' Widget 中的成员:

template<typename... Elems>
class Widget
{
std::tuple<Elems...> elements;
WidgetSignals<Elems...> signals;

Widget(vec4 quad)
: elements(initializeElements(quad))
, signals(elements) // initialized after elements because of order of member declaration
{}
// WidgetSignal member references
const typename WidgetSignals<Elems...>::SignalType& enter = signals.enter;
const typename WidgetSignals<Elems...>::SignalType& leave = signals.leave;
// ... remaining members
};

通过这两种解决方案,我可以使用 WidgetSignals 的界面通过 Widget :

Widget widget(vec4(0, 0, 20, 5));
foo(widget.enter);

但是这两个解决方案都相当笨拙和困惑,所以我真的很想有一个更好的语法,比如:

using signals;

using signals::enter;

Widget . using WidgetSignals<Elems...>::enter;实际上是可行的,但前提是 Widget已经继承自 WidgetSignals这意味着我必须再次使用中介助手类,我想避免这种情况。

最佳答案

只需将您想要首先初始化的元素粘贴到您首先继承的 [private] 基类中。例如:

template<typename... Elems>
struct WidgetPbase {
std::tuple<Elems...> elements;
}
template<typename... Elems>
class Widget
: private WidgetPbase<Elems...>
, public WidgetSignals<Elems...>
{
public:
Widget(vec4 quad)
: WidgetPbase<Elems...>{initializeElements(quad)}
, WidgetSignals<Elems...>(elements) {
}
};

作为从左到右/从上到下继承的基类,这安排了 elements 成员在访问时被初始化。唯一可能需要注意的是 virtual 基首先被初始化:如果 WdigetSignals 是一个 virtual 基,可能需要粘贴一个 virtual WidgetPbase 前面。

关于c++ - 无需继承直接访问类接口(interface)中成员的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51913648/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com