#c #class #memory-address #assignment-operator #copy-assignment
#c #класс #адрес памяти #оператор присваивания #копирование-присвоение
Вопрос:
В этом примере C класс C
имеет конструктор по умолчанию, конструктор копирования и оператор присваивания:
struct C {
C();
C(const Camp; c);
Camp; operator=(const Camp; c);
};
Реализация выглядит следующим образом с некоторым выводом для отслеживания объектов. Я добавил несколько примеров адресов в комментариях к строкам в качестве ссылки на main
программу ниже.
#include "C.h"
#include <iostream>
using namespace std;
C::C() {
cout << "Standard constructor." << endl;
}
C::C(const Camp; c) {
cout << "Copy constructor." << endl;
}
Camp; C::operator=(const Camp; c) {
cout << "Address of reference argument: amp;c = " << amp;c << endl; // F9B4
cout << "Address of this: amp;*this = " << amp;*this << endl; // F8D4
return *this;
}
Я буду использовать фабричный метод, который возвращает анонимные объекты:
C foo() {
return C();
}
Теперь в следующей программе я создаю именованный объект c
(см. (1)) и создаю анонимный объект (2), который я присваиваю c
(3). Я ожидал, что c
после назначения будет указан адрес анонимного объекта.
int main()
{
C c; // (1)
cout << "Address of initial c from main: amp;c = " << amp;c << endl; // F8D4
c=foo(); // (2) and (3)
cout << "Address of initial c from main after assignment: amp;c = " << amp;c << endl; // Expected F9B4 but is F8D4
}
Комментарии:
1.
c
является локальной переменной. Его адрес не изменится.2.
=
просто копирует внутреннее содержимое. Вы не можете изменить адрес переменной, объявленной в стеке3. Переменная — это поле с именем; внутри него хранится значение.
c
является таким полем;foo()
создает и возвращает анонимное поле. Оператор присваивания=
не влияет на поля, он копирует содержимое из одного поля в другое.4. Я не думаю, что адрес объекта можно изменить, независимо от того, размещен ли он в стеке или в свободном хранилище.
5. Стоит отметить, что если вы пришли с C # или Java, легко получить эту путаницу.
Ответ №1:
Объекты в C никогда не меняют адреса.
Оператор присваивания ничем не отличается от любого другого метода, обычно он просто перебирает все переменные-члены и присваивает им новые значения, скопированные из соответствующих членов другого объекта.
Ответ №2:
Оператор присваивания копирования не создает новый объект, он обычно изменяет элементы данных уже созданного объекта. Память для объекта с автоматической или статической продолжительностью хранения выделяется при создании объекта, как в этом объявлении
C c;
Ответ №3:
Я ожидал, что после назначения c будет иметь адрес анонимного объекта.
Объекты в C размещаются в стеке, если явно не указано new
.
В этом случае вы просто создаете временный анонимный объект, а затем копируете его c
. c
имеет то же местоположение в стеке, что и раньше.
Причина, по которой вы можете не видеть сообщение конструктора копирования c=foo();
, заключается в том, что что-то называется copy elision , по которой, я полагаю, вы думали c
, что будет храниться анонимный объект, а не просто его копия.