Область видимости закрытых переменных-членов - C ++

StackOverflow https://stackoverflow.com/questions/404513

  •  03-07-2019
  •  | 
  •  

Вопрос

Я только начинаю с C ++ и столкнулся с некоторыми проблемами в понимании того, как работает область видимости для закрытых переменных-членов в классе.Пожалуйста, ознакомьтесь с приведенным ниже кодом

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;
}

В приведенном выше коде переменная "container" является закрытой переменной-членом.Я вызываю экземпляр "Foo" и передаю его нескольким другим методам и классам.Ниже приведены мои сомнения

  1. Какова будет область действия переменной "container"?Будет ли эта переменная существовать до тех пор, пока я не удалю экземпляр foo?
  2. Нужно ли мне сделать "контейнер" в качестве указателя на вектор?

Спасибо за помощь

Это было полезно?

Решение

  1. Да, тот самый срок службы член контейнера будет существовать до тех пор, пока существует объект, который его содержит, то есть до тех пор, пока вы не вызовете delete на указателе , указывающем на него (foo в вашем случае).
  2. Нет, для этого нет никаких причин.Превращение его в указатель требует, чтобы вы создали динамический объект vector<int> который вам понадобится для управления временем жизни (включая вызов delete для указателя контейнера).Здесь в этом нет необходимости.Предполагая, что вы хотите, чтобы контейнер сохранялся столько же, сколько объект Foo, вы можете содержать его напрямую, не делая этого с помощью указателя.

Проходя мимо foo pointer просто передаст указатель.Объект, на который он указывает, будет нет может быть скопирован только указатель, указывающий на него, если это необходимо.Если вы знаете Java, то вам поможет, если я скажу вам, что передача указателя - это то же самое, что просто передача ссылки на объект в Java, скажем:

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

Другие советы

Я вызываю экземпляр "Foo"

На самом деле, вы создаете экземпляр класс Foo.

В частности, вы выделяете блок памяти из кучи с помощью новый().Этот блок памяти достаточно велик, чтобы содержать Foo:: контейнер и любой другой класс накладных расходов Фу требует.

(В этом примере такого нет.В других классах могут быть дополнительные атрибуты или, возможно, таблица виртуальных указателей.)

Естественно, новый() вызывает (возможно, по умолчанию?) Foo::Foo() конструктор, который, в свою очередь, инициализирует Foo:: контейнер через std:: вектор конструктор.

Какова будет область действия переменной "container"?

контейнер является атрибутом [компонентом] экземпляра фу.Он существует до тех пор, пока экземпляр фу существует.

С точки зрения сферы охвата, мы можем говорить о Foo:: контейнер.Но вы не можете получить доступ Foo::констейнер без экземпляра класса Фу.(Например.Объект фу.) Foo::констейнер не существует без экземпляра class Фу.

(Существуют переменные класса, которые работают несколько иначе, где одно значение является общим для всех экземпляров.Но здесь дело обстоит не так.)

Это определение является НЕУМЕСТНЫЙ к вашему общедоступному / защищенному / личному / другу-контроль доступа.

Например, в некоторых Foo::myPublicMethod() вы могли бы сослаться на Foo:: контейнер.Хотя вы также могли бы отказаться от явного определения области видимости в этой ситуации и просто ссылаться на это как контейнер.

Имейте в виду, что, будучи частным лицом, вы не можете получить доступ Foo:: контейнер вне класса Фу методы.

Будет ли эта переменная существовать до тех пор, пока я не удалю экземпляр foo?

ДА.

Нужно ли мне сделать "контейнер" в качестве указателя на вектор?

Нет.Вы можете, но вам, конечно, не обязательно это делать.

Вообще говоря, я не рекомендую, чтобы члены экземпляра класса были указателями в сочетании с new в конструкторе и delete в деструкторе.Это неэффективно и хлопотно.(Конструктор копирования по умолчанию может скопировать значение указателя, затем деструктор может удалить одно и то же значение указателя дважды.)


В зависимости от ваших потребностей, вы можете рассмотреть:

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

фу вышел бы за рамки после возвращает 0;, и будут автоматически удалены.Более того, фу будет выделен из стека, а не из кучи.


Возможно, вы найдете использованную копию Аннотированное Справочное руководство по C ++ полезный.Он старый, но у него высокое отношение сигнал / шум.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top