简体   繁体   English

私有成员变量范围-C ++

[英]Private member variables scope - C++

I am just starting with C++ and got some problems in understanding how the scope for private member variables in a class works. 我只是从C ++开始,在理解类中私有成员变量的作用域如何工作时遇到了一些问题。 Please see the below code 请看下面的代码

class Foo{
    private:
        std::vector<int> container;
    public:
        // other methods
};

int main(int argc, char* argv[])
{
    Foo* foo = new Foo;
    // other method calls to which foo is passed
    delete foo;
    return 0;
}

In the above code, variable "container" is a private member variable. 在上面的代码中,变量“容器”是私有成员变量。 I am invoking "Foo" instance and passing it to several other methods and classes. 我正在调用“ Foo”实例并将其传递给其他几种方法和类。 Following are my doubts 以下是我的疑问

  1. What will be the scope of variable "container"? 变量“容器”的范围是什么? Will that variable exist until I delete the instance foo? 在删除实例foo之前,该变量是否存在?
  2. Do I need to make the "container" as a pointer to vector? 我是否需要将“容器”作为指向矢量的指针?

Thanks for the help 谢谢您的帮助

  1. Yes, the lifetime of the container member will last as long as the object that contains it exists, which is until you call delete on the pointer pointing to it ( foo in your case). 是的,容器成员的生存期将一直持续到包含它的对象存在,直到您对指向它的指针(在您的情况下为foo )调用delete为止。
  2. No, there is no reason to do that. 不,没有理由这样做。 Making it a pointer requires you to create a dynamic object of vector<int> which you would need to manage the lifetime of (including calling delete on the container pointer). 使它成为指针要求您创建一个vector<int>的动态对象,您需要管理该对象的生命周期(包括在容器指针上调用delete)。 That's unnecessary here. 这里没有必要。 Assuming you want the container last as long as the Foo object, you are fine with having it directly contained, without doing it with a pointer. 假设您希望容器的寿命与Foo对象一样长,则可以直接包含它而无需使用指针就可以了。

Passing the foo pointer will just pass the pointer. 传递foo指针只会传递指针。 The object that it points to will not be copied, only the pointer pointing to it if necassary. 它指向的对象将不会被复制,只有在需要时才指向它的指针。 If you know Java, then it helps you if i tell you passing the pointer is the same as just passing a reference to an object in Java, say: 如果您知道Java,那么如果我告诉您传递指针与仅传递对Java中对象的引用相同,它会为您提供帮助,例如:

Foo f = new Foo();
// just passes the reference (pointer in C++) to doIt. 
// the actual object is not copied
doIt(f);

I am invoking "Foo" instance 我正在调用“ Foo”实例

Actually, you are creating an instance of class Foo . 实际上,您正在创建类Foo的实例。

Specifically, you are allocating a block of memory off the heap via new() . 具体来说,您是通过new()在堆外分配一块内存。 This block of memory is large enough to contain Foo::container and whatever other overhead class Foo requires. 该内存块足够大,可以容纳Foo :: container以及Foo所需的任何其他开销类。

(In this example, there is none. With other classes, there might be additional attributes or perhaps a virtual-pointer table.) (在此示例中,没有任何属性。对于其他类,可能会有其他属性或虚拟指针表。)

Naturally, new() invokes the (perhaps default?) Foo::Foo() constructor, which in turn initializes Foo::container through the std::vector constructor. 自然地, new()调用(也许是默认的?) Foo :: Foo()构造函数,后者又通过std :: vector构造函数初始化Foo :: container

What will be the scope of variable "container"? 变量“容器”的范围是什么?

container is an attribute [component] of the instance foo . container是实例foo的属性[component]。 It exists as long as the instance foo exists. 只要实例foo存在,它就存在。

Scope-wise, we can speak of Foo::container . 在范围上,我们可以说Foo :: container But you cannot access Foo::constainer without an instance of class Foo . 但是,如果没有类Foo的实例,则无法访问Foo :: container (Eg The object foo .) Foo::constainer doesn't exist without an instance of class Foo . (例如,对象foo 。)没有类Foo的实例, Foo :: container不存在。

(There are class-variables that work somewhat differently, where one value is shared across all instances. But that is not the case here.) (有些类变量的工作方式有所不同,其中一个值在所有实例之间共享。但这不是这种情况。)

This scoping is IRRELEVANT to your public/protected/private/friend member-access-control. 此作用域与您的公共/受保护/私人/朋友成员访问控制无关

Eg, in some Foo::myPublicMethod() you could refer to Foo::container . 例如,在某些Foo :: myPublicMethod()中,您可以引用Foo :: container Though you could also forgo the explicit scoping in this situation and just refer to it as container . 尽管您也可以在这种情况下放弃显式作用域,而仅将其称为容器

Mind you, being private, you can't access Foo::container outside of class Foo's methods. 请注意,作为私有用户,您不能在Foo方法之外访问Foo :: container

Will that variable exist until I delete the instance foo? 在删除实例foo之前,该变量是否存在?

Yes. 是。

Do I need to make the "container" as a pointer to vector? 我是否需要将“容器”作为指向矢量的指针?

No. You can, but you certainly don't have to. 不可以。但是您当然不必。

Generally speaking, I recommend against class instance members being pointers coupled with new in the constructor and delete in the destructor. 一般而言,我建议不要将类实例成员用作构造函数中的new指针和析构函数中的delete指针。 It's inefficient and troublesome. 它效率低下且麻烦。 (The default copy constructor can copy the pointer value, the destructor can then delete the same pointer value twice.) (默认的复制构造函数可以复制指针值,然后析构函数可以将相同的指针值删除两次。)


Depending on your needs, you might consider: 根据您的需求,您可以考虑:

int main(int argc, char* argv[])
{
  Foo foo;
  // other method calls to which foo is passed
  return 0;
}

foo would go out of scope after return 0; foo将在返回0后超出范围 , and be automatically deleted. ,并被自动删除。 Moreover, foo would be allocated off the stack rather than the heap. 而且, foo将从栈而不是堆中分配。


You might find a used copy of The Annotated C++ Reference Manual useful. 您可能会发现《带注释的C ++参考手册》的二手副本很有用。 It's old, but it has a high signal-to-noise ratio. 它虽然很旧,但是信噪比很高。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM