本文介绍了组成:使用traits避免转发功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有两个类, A B 。当使用组合来建模has-ais-implemented-in-terms-of关系(例如 B has-a A ),缺点与继承之一是 B 不包含它需要的 A 的公共功能。为了访问 A 的公共函数,有必要提供转发功能(与继承相反, B 将继承所有 A 的公共函数)。

Let's say we have two classes, A and B. When using composition to model a "has-a" or "is-implemented-in-terms-of" relationship (e.g. B has-a A), one of the drawbacks vs. inheritance is that B does not the contain public functionality of A that it requires. In order to gain access to As public functions, it is necessary to provide forwarding functions (as opposed to inheritance, where B would inherit all of As public functions).

为了给出一个更具体的例子,有,其中 ContactInfo

To give a more concrete example, let's say we have a Person which has-a ContactInfo:

using namespace std;

class ContactInfo
{
public:
   ContactInfo();
   void updateAddress(string address);
   void updatePhone(string phone);
   void updateEmail(string email);
private:
   string address;
   string phone;
   string email;
};

class Person
{
public:
   Person();
   // Forwarding functions:
   void updateAddress(string address){contactInfo.updateAddress(address)};
   void updatePhone(string phone){contactInfo.updatePhone(phone)};
   void updateEmail(string email){contactInfo.updateEmail(email)};
private:
   ContactInfo contactInfo;
};

忽略设计中的任何缺陷(这只是一个假设的示例,必须非常繁琐地复制 Person ContactInfo 的确切函数签名。在一个更复杂的例子中,可能有许多这样的函数和许多层的组成类,导致许多代码重复与所有常见的维护问题和容易出错等。

Ignoring any deficiencies in the design (it is just a contrived example to demonstrate my question below), I have had to tediously replicate the exact function signatures from ContactInfo in Person. In a more complex example there could be many such functions, and many layers of composed classes, leading to much code duplication with all the usual problems of maintenance and being error-prone, etc.

尽管如此,这是根据诸如项目的来源建模has-a的实施条款38的Meyers的有效C + +,和Sutter的异常C ++项目24()。

Nonetheless, this is the recommended practice for modelling "has-a" or "is-implemented-in-terms-of" according to sources such as Item 38 of Meyers' Effective C++, and Item 24 of Sutter's Exceptional C++ (link).

在研究这个问题时,我遇到了,讨论同一主题。 ,建议如下:

Whilst researching this, I came across this Wikipedia article which discusses the same topic. At the bottom of the article, it suggests the following:

我是traits的概念,已经阅读,我发现很难与上述语句相关。因此我的问题是:如何使用traits避免使用组合转发函数?基于我的示例的答案( Person ContactInfo )是理想的。

I am fairly new to the concept of traits and with everything I have read, I am finding it hard to relate to the above statement. My question therefore is: How would one go about using traits to avoid forwarding functions with composition? An answer based on my example (Person and ContactInfo) would be ideal.

EDIT:答案,我知道私人继承作为一个替代组合的建模is-implemented-in-terms-of。我的问题不是关于这一点,它具体是关于维基百科的语句与性状的意义。我不是要求组合的替代品。

Just to clarify, in response to some of the answers, I am aware of private inheritance as an alternative to composition for modelling "is-implemented-in-terms-of". My question is not about that, it is specifically about the meaning of Wikipedia's statement relating to traits. I am not asking for alternatives to composition. I've bolded my question to make it clearer that this is what I'm asking.

推荐答案

首先我应该提到的是这些特征在C ++ / STL和像PHP,Lasso等语言中是不同的。看起来像来自wikipedia的文章指的是类似PHP的traits,因为C ++ / STL traits不是为多态重用而设计的(我们说的是多态的代码重用行为,对吧?它们旨在简化模板类的声明。

First of all I should mention that traits are different things in C++/STL and languages like PHP, Lasso etc. It looks like the article from wikipedia refers to PHP-like traits because C++/STL traits are not designed for polymorphic reuse (we are speaking about code reuse with polymorphic behavior, right?). They designed to simplify declaration of template classes.

在一些不支持多继承(PHP,Lasso等)的语言中使用traits。 Traits允许模仿多重继承(但是多重继承和特征不完全一样)。

Traits are used in some languages that don't support multiple inheritance (PHP, Lasso etc). Traits allow to "emulate" multiple inheritance (but multiple inheritance and traits are not exactly the same).

相反,C ++不支持PHP-traits, 。所以如果谈到C ++,那么trait样解决方案将是这样的:

In contrast C++ doesn't support PHP-traits but supports multiple inheritance. So if speaking about C++ then trait-like solution will be something like this:

class VisibleTrait
{
    public:
        virtual void draw();
};

class SolidTrait
{
    public:
        virtual void collide(Object objects[]);
};

class MovableTrait
{
    public:
        virtual void update();
};


// A player is visible, movable, and solid
class Player : public VisibleTrait, MovableTrait, SolidTrait
{
};

// Smoke is visible and movable but not solid
class Smoke : public VisibleTrait, MovableTrait
{
};

// A hause is visible and solid but not movable
class House : public VisibleTrait, SolidTrait
{
};

回答你的问题

1)Traits不会避免使用合成转发函数,因为traits独立于合成工作。 (Wikipadia的文章对于特性和组成之间的关系有一点误导)

2)PHP / Lasso-like traits可以在C ++中用多重继承来部分模拟。

1) Traits don't avoid forwarding functions with composition because traits work independently from composition. (The article from Wikipadia is misleading a little regarding the relationship between traits and composition)
2) PHP/Lasso-like traits can be partially emulated in C++ with multiple inheritance.

这篇关于组成:使用traits避免转发功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 18:41