Javier Luis Lopez Ответов: 2

Право копировать классов Анс структура, содержание?


Я сделал следующий код для копирования содержимого структуры и классов. Результат в порядке в VS C++, но я не знаю, правильно ли это в linux.
Есть программисты, которые говорили о "неглубоком копировании" и необходимости использования strdup, см. здесь 4-й ответ "paxdiablo":
http://stackoverflow.com/questions/4931123/copying-one-structure-to-another

но я проверил это с помощью VS2013 и не увидел никакой " теневой копии":

Что я уже пробовал:

#include <iostream>


struct s_struct
{
	int a, b;
	double w;
}s1,s2,s3,s4;

class c_class
{
public:
	int a, b;
	double w;
}c1,c2,c3;


using namespace std;


void main()
{
	s1.a = 10; s1.b = 12; s1.w = 100.111;
	memcpy(&s2, &s1, sizeof(s_struct));
	s3 = s1;
	if ((&s1 == &s3) || (&s1==&s2))
		cout << "STUPID copy of structures" << endl;
	else
		cout << "right copy of structures" << endl;
	c1.a = 22; c1.b = 24; c1.w = 200.222;
	memcpy(&c2, &c1, sizeof(c_class));
	c3 = c1;
	if ((&c1 == &c3) || (&c1 == &c2))
		cout << "STUPID copy of classes" << endl;
	else
		cout << "right copy of classes" << endl;


	cout << "=================== END ======================" << endl << endl;
	getchar(); getchar();
}

2 Ответов

Рейтинг:
9

Jochen Arndt

Это нормально просто скопировать память, когда ваш класс или структура содержит только фундаментальные члены (is_fundamental-ссылка на C++ [^]) как в вашем примере.

Обратите внимание, что обычно существует неявно объявленный оператор присваивания копии, который обрабатывает также члены класса (вызывает их оператор копирования). Видеть Оператор назначения копирования - cppreference.com[^].

Если ваш класс выделяет память, хранящую указатель в переменной-члене, вы всегда должны предоставить оператор копирования (как в упомянутой ссылке SO, где strdup используется для копирования содержимого выделенной строки).

Для Windows и Linux нет никакой разницы. Это просто C++.


Javier Luis Lopez

Оператор копирования-это способ.

Копирование структуры или класса в символьный массив также было бы полезно отправить его через tcpip или сохранить в файле таким образом:

char *buffer=new char[sizeof(class_tobe_copied)];
memcpy(buffer,&class_tobe_copied,sizeof(class_tobe_copied));

//...transmit the data
//Recover the class to class2:
memcpy(&class2,buffer,sizeof(class2));


У меня есть сомнения:
Безопасен ли этот метод с использованием различных ОС и компиляторов на стороне кодирования и декодирования?

Jochen Arndt

Обычно это небезопасно, так как оператор sizeof() может возвращать разные размеры. Чтобы обеспечить идентичные размеры, вы должны использовать идентичные методы упаковки (см. #pragma pack для VC и _ _ attribute__((packed)) для GCC).

Ваш пример также потерпит неудачу, если он содержит не фундаментальные члены.

Рейтинг:
16

Richard MacCutchan

Это нормально, но это не сработало бы, если бы структура или класс содержали указатели на другие объекты. Вы должны создать правильные конструкторы копирования, как описано в разделе Конструкторы копирования и операторы присваивания копирования (C++)[^].

Обратите внимание также, что это не имеет ничего общего с Windows или Linux, это чисто проблема для C++.