C++ CPP:作为另一个类中的私人成员的类

C++ CPP:作为另一个类中的私人成员的类,c++,class,methods,C++,Class,Methods,例如,我创建了一个Button类按钮应该有自己的文本(颜色、大小、字体、间距等)、状态和背景 因为文本标签即使在其他小部件(文本标签、文本编辑等)中也很有用,所以我将所有需要的都放在另一个类中(称之为Label) 背景色也很有用,所以我创建了另一个类-color,包含所有需要的方法-更改、比较 现在回到按钮类 class Button { private: Color _bgColor; Label _text; /* another p

例如,我创建了一个Button类<代码>按钮应该有自己的文本(颜色、大小、字体、间距等)、状态和背景

因为文本标签即使在其他小部件(文本标签、文本编辑等)中也很有用,所以我将所有需要的都放在另一个类中(称之为
Label

背景色也很有用,所以我创建了另一个类-
color
,包含所有需要的方法-更改、比较

现在回到按钮类

class Button {
    private:
        Color _bgColor;
        Label _text;

        /* another private members */

    public:
        /* Content of Button class */
};
但是如果我想改变按钮的背景色呢?在本例中,我需要编写另外两个方法=>
setColor
getColor
。事实上,我必须编写为
Color
类定义的所有方法

另一个选项是将私有类定义为公共类,并像
button.bgColor.setColor()
那样访问它们。但对我来说,一次调用
按钮。禁用
和另一次调用
按钮。color.setColor
似乎很奇怪

还有其他我不知道的选择吗?谢谢你的帮助

但是如果我想改变按钮的背景色呢?在这种情况下,我需要 编写另外两个方法=>setColor和getColor。实际上,我必须编写为Color类定义的所有方法

你为什么要那样做? 只需定义一个函数
SetBackgroundColor(Color&newColor)
来设置颜色,并
const Color&GetBackgroundColor()const
来访问它

但是如果我想改变按钮的背景色呢?在本例中,我需要编写另外两个方法=>
setColor
getColor
。事实上,我必须编写为
Color
类定义的所有方法

不是真的。您只需要编写这两个方法。其他任何事情都是通过
getColor
返回值发生的。例如,要测试两个按钮是否具有相同的颜色,请编写:

if (button1.getColor() == button2.getColor())
不是


也就是说,除非您想隐藏
按钮
使用
颜色
类作为“实现细节”。我不建议这样做。处理颜色的程序通常应将颜色视为一种值类型,类似于普通数字、点、向量等。

你是正确的,当某些东西具有属性时,这些属性需要以某种方式公开,这可能会导致代码膨胀。然而,与所有事物一样,一个简单的抽象层可以使事情变得更容易

您可以为这些类型的属性提供“帮助器类”,并将它们用作混合。这将使代码在静止时尽可能小

class HasLabel
{
public:
   void SetLabelText(const std::string& text);
   const std::string& GetLabelText() const;

private:
   Label label_;
};

class HasBackgroundColor
{
public:
   void SetBackgroundColor(const Color& color);
   const Color& GetBackgroundColor() const;

private:
   Color color_;
};

class Button : private HasBackgroundColor, private HasLabel
{
public:
   // Expose BkColor
   using HasBackgroundColor::SetLabelText;
   using HasBackgroundColor::GetLabelText;

   // Expose Label
   using HasLabel::SetLabelText;
   using HasLabel::GetLabelText;
};
您也可以使用公共继承,这样就不需要使用
指令
,但这是否可以接受(如果
按钮
确实“是-a”
HasLabel
)取决于个人偏好


您还可以使用来减少具有类似混合的对象的样板代码量。

我认为您已经很好地总结了您的选择。很高兴知道:)嗯,没有比使用类作为公共方法更好的解决方案了?使用
friend
是设计错误的标志。这完全取决于您对方便与封装的重视程度。作为懒惰的人,我可能更喜欢方便。另一方面,我应该在
按钮
-类中从一开始就“以良好的方式”做事。(函数和方法之间有区别吗?)我认为方法是类中使用的函数。类::方法(),但函数()这会导致长的“访问”链。例如,与其使用
button.setFont(button2.setFont())
,不如使用
button.getFont().setFont(button2.getFont())
。我知道,这是个糟糕的例子。你的第一行是指
button.setFont(button2.getFont())
?你的代码可以用。但正如我所说的,它会导致很长的源代码。在使用它之前,您必须始终调用.getColor。没什么了。你评论中的第二行代码没有意义。为什么
Font
会有一个
setFont()
方法?这看起来不错。但是我看不出这和haansn08的答案有什么区别。除此之外,此方法还需要另外两个类。同意,如果所讨论的唯一对象类型是
按钮
。但是,如果有其他具有类似属性的对象类型(
ScrollBar
ListBox
),这些混合提供了一种方法,可以减少样板代码,增加共享代码(随着时间的推移,使维护变得更容易)。
class HasLabel
{
public:
   void SetLabelText(const std::string& text);
   const std::string& GetLabelText() const;

private:
   Label label_;
};

class HasBackgroundColor
{
public:
   void SetBackgroundColor(const Color& color);
   const Color& GetBackgroundColor() const;

private:
   Color color_;
};

class Button : private HasBackgroundColor, private HasLabel
{
public:
   // Expose BkColor
   using HasBackgroundColor::SetLabelText;
   using HasBackgroundColor::GetLabelText;

   // Expose Label
   using HasLabel::SetLabelText;
   using HasLabel::GetLabelText;
};