Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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++ 将对象创建为私有成员变量vs.在成员函数中_C++_Oop_Object_Private Members_Member Functions - Fatal编程技术网

C++ 将对象创建为私有成员变量vs.在成员函数中

C++ 将对象创建为私有成员变量vs.在成员函数中,c++,oop,object,private-members,member-functions,C++,Oop,Object,Private Members,Member Functions,在类声明中将对象创建为私有成员变量与在类的方法定义中创建对象之间有什么区别?我知道明显的区别是一个是全局变量,另一个是局部变量。在什么情况下我应该做前者和后者 Aclass.h class Aclass{ private: AnotherClass someobj1; //option 1 public: void someMethod(); }; Aclass.cpp void Aclass::someMethod(){ AnotherClass some

在类声明中将对象创建为私有成员变量与在类的方法定义中创建对象之间有什么区别?我知道明显的区别是一个是全局变量,另一个是局部变量。在什么情况下我应该做前者和后者

Aclass.h

class Aclass{ 
private: 
    AnotherClass someobj1; //option 1
public:  
    void someMethod(); 
};
Aclass.cpp

void Aclass::someMethod(){ 
    AnotherClass someobj2; //option 2 
}

someobj1
确实是一个成员变量。这意味着
AClass
的每个实例都包含另一个名为
someobj1
的类的
实例,该类的生存期与其所属的实例相同

someobj2
someMethod
函数的局部变量。它将在上述功能结束时被销毁

它们都不是全球性的。可能您将它们与静态成员变量混合在一起,这些变量具有静态生存期(在
main
开始之前构造,在结束之后销毁),就像全局变量一样(但它们并不完全是全局的,因为它们包含在类的作用域中)

下面是一个愚蠢的例子,可以非常清楚地说明这一点:

CatBasket gCatBasket; // All cats in the house share the same basket (global)

class Cat {
    Tail _tail; // The tail is part of the cat (member)
    Human *_owner; // The cat remembers his owner for his whole life (member)

    void meow() {
        MeowSound sound; // The "meow" sound only exists while the cat is meowing. (local)
        sound.setAmplitude(17.0f);
        sound.setPurr(true);

        sound.play();
    }

    static bool _beACat;
};

bool Cat::_beACat = true; // Everybody wants to be a cat (static)

someobj1
确实是一个成员变量。这意味着
AClass
的每个实例都包含另一个名为
someobj1
的类的实例,该类的生存期与其所属的实例相同

someobj2
someMethod
函数的局部变量。它将在所述函数结束时被销毁

它们都不是全局变量。可能您将它们与静态成员变量混合在一起,这些变量具有静态生存期(在
main
开始之前构造,在结束之后销毁),就像全局变量一样(但它们不完全是全局变量,因为它们包含在类的范围内)

下面是一个愚蠢的例子,可以非常清楚地说明这一点:

CatBasket gCatBasket; // All cats in the house share the same basket (global)

class Cat {
    Tail _tail; // The tail is part of the cat (member)
    Human *_owner; // The cat remembers his owner for his whole life (member)

    void meow() {
        MeowSound sound; // The "meow" sound only exists while the cat is meowing. (local)
        sound.setAmplitude(17.0f);
        sound.setPurr(true);

        sound.play();
    }

    static bool _beACat;
};

bool Cat::_beACat = true; // Everybody wants to be a cat (static)

我们可以使用对象作为私有成员来定义关联组合聚合等概念

考虑以下代码段:

//ASSOCIATION
class Bar
{
    Baz baz;
};
class Foo
{
    Bar* bar;
    void setBar(Bar* _bar)
    {
        bar=_bar;
    }
};

//AGGREGATION
class Bar
{
    Baz baz;
};

class Foo
{
    Bar* bar;
    void setBar(Bar* _bar)
    {
        bar = new Bar;
        bar->baz=_bar->baz;
    }
};


//COMPOSTION
class Bar
{
    Baz baz;
};
class Foo
{
    Bar bar;
}
我的理解是:

  • 关联:Foo有一个指向Bar对象的指针作为数据成员
  • 聚合:Foo有一个指向Bar对象的指针,Bar的数据被深度复制到该指针中
  • 组合:Foo有一个Bar对象作为数据成员
  • 但是,如果要在较短的时间内(而不是在包含该对象的对象的整个生命周期内)使用该对象,则需要使用第二种类型(在成员函数定义中创建对象)

    另一个区别是关于内存:

    作为数据成员的对象将被分配内存并保留到 对象死亡。但是,该对象将作为成员中的变量 每当 功能超出范围


    我们可以使用对象作为私有成员来定义关联组合聚合等概念

    考虑以下代码段:

    //ASSOCIATION
    class Bar
    {
        Baz baz;
    };
    class Foo
    {
        Bar* bar;
        void setBar(Bar* _bar)
        {
            bar=_bar;
        }
    };
    
    //AGGREGATION
    class Bar
    {
        Baz baz;
    };
    
    class Foo
    {
        Bar* bar;
        void setBar(Bar* _bar)
        {
            bar = new Bar;
            bar->baz=_bar->baz;
        }
    };
    
    
    //COMPOSTION
    class Bar
    {
        Baz baz;
    };
    class Foo
    {
        Bar bar;
    }
    
    我的理解是:

  • 关联:Foo有一个指向Bar对象的指针作为数据成员
  • 聚合:Foo有一个指向Bar对象的指针,Bar的数据被深度复制到该指针中
  • 组合:Foo有一个Bar对象作为数据成员
  • 但是,如果要在较短的时间内(而不是在包含该对象的对象的整个生命周期内)使用该对象,则需要使用第二种类型(在成员函数定义中创建对象)

    另一个区别是关于内存:

    作为数据成员的对象将被分配内存并保留到 对象死亡。但是,该对象将作为成员中的变量 每当 功能超出范围

    成员变量(无论其可见性如何)贯穿实例的生命周期。只要您有
    AClass
    的活动实例,它将保留
    someobj1
    的值。这些类型的变量(传统上)用于保存对象的状态,您希望从一种用法保存到另一种用法

    方法中定义的局部变量只是一个局部变量。它是一个辅助变量,可以帮助您执行方法的功能,并且在方法调用结束后没有意义(也不存在)。

    成员变量(无论其可见性如何)在实例的生命周期中始终存在。只要您有一个
    AClass
    的活动实例,它将保留
    someobj1
    的值。这些类型的变量(传统上)用于保存对象的状态,您希望从一种用法保存到另一种用法


    方法中定义的局部变量只是一个局部变量。它是一个辅助变量,可以帮助您执行方法的功能,一旦方法调用结束,它就没有意义(也不存在)。

    最重要的区别是另一个类实例的寿命

    A类h

    class Aclass{ 
    private: 
        AnotherClass someobj1; //option 1: This instance is accessible from within the Aclass instance as long as the Aclass instance is not destroyed.
    public:  
        void someMethod(); //option 1: So someobj1 is available (for reading AND writing in this method. When you call this method twice, you will work with the same instance each time.
        void someMethodToo(); //option 1: someobj1 will also be available in this method for reading AND writing.
    };
    
    Aclass.cpp

    void Aclass::someMethod(){ 
        AnotherClass someobj2; //option 2: This instance is destroyed when someMethod is done. The method someMethodToo that I described above will never have access to someobj2 either. If you call someMethod twice, each will have it's own someobj2. 
    }
    

    最重要的区别是另一个类实例的生命周期

    A类h

    class Aclass{ 
    private: 
        AnotherClass someobj1; //option 1: This instance is accessible from within the Aclass instance as long as the Aclass instance is not destroyed.
    public:  
        void someMethod(); //option 1: So someobj1 is available (for reading AND writing in this method. When you call this method twice, you will work with the same instance each time.
        void someMethodToo(); //option 1: someobj1 will also be available in this method for reading AND writing.
    };
    
    Aclass.cpp

    void Aclass::someMethod(){ 
        AnotherClass someobj2; //option 2: This instance is destroyed when someMethod is done. The method someMethodToo that I described above will never have access to someobj2 either. If you call someMethod twice, each will have it's own someobj2. 
    }
    

    编程的绝对规则是在绝对必要时定义、声明或初始化某些内容。这意味着它将明显降低内存和性能成本。
    也就是说,当您在类中声明成员变量时,每当创建新对象时,都会为其分配内存空间。因此,除非您在每个对象中都需要它,否则不要在类范围中声明它。
    当您不需要任何函数或CLA时,再次声明变量private是必要的