Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 让孩子接触父母';s会员的推荐信-可以吗?_C++_Class_Class Design_Pass By Reference - Fatal编程技术网

C++ 让孩子接触父母';s会员的推荐信-可以吗?

C++ 让孩子接触父母';s会员的推荐信-可以吗?,c++,class,class-design,pass-by-reference,C++,Class,Class Design,Pass By Reference,C++新手问题。请确认我做得对 我有一个全局应用程序类,它的孩子,我需要让孩子们访问一些应用程序设施。所以我决定通过参考把它们传给孩子们 我测试了这个想法,如下所示。它似乎工作得很好。我只是想确定我没有做什么危险的事。可能有我忽略的陷阱吗 爸爸创造了孩子并给他们车钥匙: #包括 使用名称空间std; C类市场 { 公众: CCarKeys(常量字符串和名称):\u Name(名称){} 字符串\u名称; }; 儿童班 { 公众: 儿童(车钥匙和车钥匙):_姓名(“儿童”),_车钥匙(车钥匙){}

C++新手问题。请确认我做得对

我有一个全局应用程序类,它的孩子,我需要让孩子们访问一些应用程序设施。所以我决定通过参考把它们传给孩子们

我测试了这个想法,如下所示。它似乎工作得很好。我只是想确定我没有做什么危险的事。可能有我忽略的陷阱吗

爸爸创造了孩子并给他们车钥匙:

#包括
使用名称空间std;
C类市场
{
公众:
CCarKeys(常量字符串和名称):\u Name(名称){}
字符串\u名称;
};
儿童班
{
公众:
儿童(车钥匙和车钥匙):_姓名(“儿童”),_车钥匙(车钥匙){}
字符串\u名称;
CCarKeys&uCarkeys;
void TestHasKeys(){cout对我来说很好(如果密钥是他们所需要的)。他们可能需要Dad提供的其他服务,这些服务稍后会被请求-例如:

Wallet += MyDad.GasMoney(REQUEST_MAX_AND_PROMISE_TO_BE_HOME_BY_10PM) ;
但是他们没有对Dad的引用,所以他们不能这样做。所以我会让CChild构造函数也采用
this
引用

class ICashProvider {
public:
  virtual money Request(IPerson,CashRequestFlags) ;
};

class IChaffeur {
public:
  virtual void Drive(IPerson[]) ;
};
等等


然后
CChild
构造函数需要使用
iCasProvider
iChaffer
,就像
cLife
CGirlfriend
一样(可能还有
CBoyfriend
)。在这一点上,我想您可能会意识到,面对
Dad
的责任,这种粒度级别是毫无意义的,您只需给每个人
this
,让
Dad
通过强制调用方在某些方法上发送自己的
this
来验证请求,因此您就没有
Dad
执行乱伦或更改
CWife
的尿布。

通过引用传递与通过指针传递完全相同,只是语义不同,如果通过引用传递,则无法处理指针本身


您的代码没有问题。

在您的特殊情况下,汽车钥匙不可能永久授予,而是根据需要请求,并根据每个请求授予。因此,它更重要

class Dad
{
   /** may return NULL if no keys granted */
   CarKeys *requestKeys(CChild forChild);
}

对于主应用程序类和子应用程序,在main()中创建应用程序和子应用程序共享的数据对象怎么样,并将引用传递给每个人。

这是可能的,并且在代码中不会造成伤害。但这是危险的,因为如果复制CDad,则会复制键和指针。但是,指针将指向的对象以及这些对象内的引用将保持不变。如果原始CDad对象继续,则s超出范围,指针引用的对象中的引用悬空,不再引用有效对象

也许你可以反转生命周期:在堆上创建密钥,并将子类作为类中的普通成员。因此,如果你复制dad,子类将被复制,但密钥不是。我认为密钥是不可变的,因此你可以在多个子类之间共享同一个密钥

这就引出了另一个问题:如果您的密钥相当小(读:不是很大)且不可变(因此,如果您更改一个密钥,而不是其他密钥,则不会出现更新异常)考虑不要在堆上创建它,所以它们也会自动复制,当他们需要钥匙的时候把它们传给孩子们。你可以让他们成为孩子们的正常指针,但是我认为这很难看,因为孩子不包含一个键,而是使用它。所以一个指针/引用或一个函数参数很好,但不是一个“真实”。数据成员

如果您要使用共享密钥和堆上的密钥,您应该使用智能指针,因为您必须跟踪所有孩子和爸爸。如果最后一个孩子/爸爸超出范围,您必须再次删除密钥。为此,您可以使用
boost::shared\u ptr

class CCarKeys
{
    public:
        CCarKeys(const string& Name) : _Name(Name) {}
        string _Name;
};

class CChild
{
    public:
        CChild(boost::shared_ptr<CCarKeys> const& CarKeys) 
            : _Name("Child"), _CarKeys(CarKeys) {}
        string _Name;
        boost::shared_ptr<CCarKeys> _CarKeys;
        void TestHasKeys() {cout << "I got " << _CarKeys._Name << endl;}
};

class CDad
{
    public:
        // NOTE: null the kid pointers *if* you use raw pointers, so you can check whether
        // a boy or girl is present. Without nulling them explicitly, they have 
        // indeterminate values. Beware. shared_ptr's however will automatically
        // initialized to default "null" values
        CDad() : 
            _Name("Dad"), 
            _HondaCarKeys(new CCarKeys("Honda keys")), 
            _ChevyCarKeys(new CCarKeys("Chevy keys")) {}
        string _Name;

        boost::shared_ptr<CCarKeys> _HondaCarKeys;
        boost::shared_ptr<CCarKeys> _ChevyCarKeys;

        // also use shared_ptr for the kids. try to avoid raw pointers. 
        boost::shared_ptr<CChild> _Boy;
        boost::shared_otr<CChild> _Girl;

        void MakeBoy() {_Boy.reset(new CChild(_HondaCarKeys));}
        void MakeGirl() {_Girl.reset(new CChild(_ChevyCarKeys));}
};

// main can be used unchanged
如果我必须实现这样的类层次结构,我会使用该解决方案,或者干脆将键作为成员丢弃,并在需要时将它们传递/创建给子级。有关代码的其他一些说明:

  • 最好从成员中删除“或”,或者把它们放在末尾,或者使用其他的符号。用下划线开头的字母后面跟着大写字母,这是由C++实现(编译器,C++ +STD LIB…)保留的。
  • 我个人觉得让成员名和变量以大写字母开头会让人困惑。我很少看到这种情况。但这并不重要,只是个人风格
  • 有一条著名的规则()规定,当你有两样东西的时候,你通常应该可以任意拥有很多东西。因此,如果你能有两个孩子,为什么不生很多孩子呢?两个孩子似乎是一个任意的选择。但在你的情况下,这可能有一个很好的理由,所以在你的情况下,忽略这一点是有意义的

如果一个孩子有这个指针,它就可以使用爸爸的设备,而这些设备应该只有妈妈才能使用。这听起来让我很害怕。只把需要的东西传递给孩子不是更好吗?不幸的是,一个班级只提供一套公共服务,为了让不同的班级可以使用爸爸的一些服务,我想你应该uld需要将Dad分解为不同的服务,并将其作为接口公开,只将接口传递给孩子、妻子等。甚至有关于这一点的电影-Dad将其接口拆分,并将不同的版本(例如,使用重写的方法getFamilyStatus())传递给不同的对象。:-)我相信这通常称为代理模式(const foo&)可以容纳一个临时值。{foo(F(1))}。用指针这样做比较困难。给定使用(F*),foo(F&a){USE(&a);}和foo(F*a){USE(a);}之间没有区别。我很忙,所以我不会费心去查找他所说的内容。有人能启发我吗?任何这样做的人都会得到一块饼干:)
class CCarKeys
{
    public:
        CCarKeys(const string& Name) : _Name(Name) {}
        string _Name;
};

class CChild
{
    public:
        CChild(boost::shared_ptr<CCarKeys> const& CarKeys) 
            : _Name("Child"), _CarKeys(CarKeys) {}
        string _Name;
        boost::shared_ptr<CCarKeys> _CarKeys;
        void TestHasKeys() {cout << "I got " << _CarKeys._Name << endl;}
};

class CDad
{
    public:
        // NOTE: null the kid pointers *if* you use raw pointers, so you can check whether
        // a boy or girl is present. Without nulling them explicitly, they have 
        // indeterminate values. Beware. shared_ptr's however will automatically
        // initialized to default "null" values
        CDad() : 
            _Name("Dad"), 
            _HondaCarKeys(new CCarKeys("Honda keys")), 
            _ChevyCarKeys(new CCarKeys("Chevy keys")) {}
        string _Name;

        boost::shared_ptr<CCarKeys> _HondaCarKeys;
        boost::shared_ptr<CCarKeys> _ChevyCarKeys;

        // also use shared_ptr for the kids. try to avoid raw pointers. 
        boost::shared_ptr<CChild> _Boy;
        boost::shared_otr<CChild> _Girl;

        void MakeBoy() {_Boy.reset(new CChild(_HondaCarKeys));}
        void MakeGirl() {_Girl.reset(new CChild(_ChevyCarKeys));}
};

// main can be used unchanged
class CCarKeys
{
    public:
        CCarKeys(const string& Name) : _Name(Name) {}
        string _Name;
};

class CChild
{
    public:
        CChild (CCarKeys& CarKeys) 
            : _Name("Child"), _CarKeys(CarKeys) {}
        string _Name;
        CCarKeys &_CarKeys;
        void TestHasKeys() {cout << "I got " << _CarKeys._Name << endl;}
    private:
        CChild(CChild const&); // non-copyable
        CChild & operator=(CChild const&); // non-assignable
};

class CDad
{
    public:
        CDad() : 
            _Name("Dad"), 
            _HondaCarKeys("Honda keys"), 
            _ChevyCarKeys("Chevy keys") {}
        string _Name;

        CCarKeys _HondaCarKeys;
        CCarKeys _ChevyCarKeys;

        // also use shared_ptr for the kids. try to avoid raw pointers. 
        boost::shared_ptr<CChild> _Boy;
        boost::shared_otr<CChild> _Girl;

        void MakeBoy() {_Boy.reset(new CChild(_HondaCarKeys));}
        void MakeGirl() {_Girl.reset(new CChild(_ChevyCarKeys));}
private:
    CDad(CDad const&); // non-copyable
    CDad & operator=(CDad const&); // non-assignable
};