C/C++结构体的正确打开方式

29 篇文章 2 订阅

        简单的C/C++结构体,一般就定义数据成员,而已,如:

struct S_Book
{	
    CString csName;
	CString csAuthor;
	float fPrice;
	short int nVersion;
};

        这熟悉的代码在很多程序里面都能看到,因为很多程序员都是这样写的。那么,有问题吗?一般场景没有问题,然而对应稍微复杂些的场景,就不够用了,甚至能让程序崩溃。比如,它不能直接赋值,它没有拷贝构造函数,如果数据成员有指针,呵呵。。那么,结构体正确的标配是怎样的呢,没有统一答案,不过,根据本人经验,至少包括构造函数、初始化函数、拷贝构造函数和赋值函数吧,如下是“标配”,至于是否需要重载加减乘除等,那是特殊情况了。

        那么,下面的“标配”,代码有问题吗?

struct S_Book
{	
    CString csName;
	CString csAuthor;
	float fPrice;
	short int nVersion;
	S_Book()
	{
		Init();
	}
	void Init()
	{
		csName.Empty();
		csAuthor.Empty();
		fPrice = 999999;
		nVersion = 9999;
	}
	S_Book(const S_Book& stItem)
	{
		csName = stItem.csName;
		csAuthor = stItem.csAuthor;
		fPrice = stItem.fPrice;
		nVersion = stItem.nVersion;
	}
	S_Book& operator= (const S_Book& stItem)
	{
		if(this == &stItem)
		{
	        return *this;
		}
		memset(this,0,sizeof(S_Book));
		memcpy(this,&stItem,sizeof(S_Book));

		return *this;
	}
};

 

        答案是 有的。在release版本不提示问题,但是在debug时,出现_CtrIsValidHeapPointer(pUserData)错误。为什么呢,如果把CString类型的数据成员删除掉,就不会出现这个问题。原因是CString类型内部有释放内存机制,内存操作函数操作内存时,出现了错误,所以解决方法就知道是什么了。

那么,C/C++结构体的正确打开方式:

struct S_Book
{	
    CString csName;
	CString csAuthor;
	float fPrice;
	short int nVersion;
	S_Book()
	{
		Init();
	}
	void Init()
	{
		csName.Empty();
		csAuthor.Empty();
		fPrice = 999999;
		nVersion = 9999;
	}
	S_Book(const S_Book& stItem)
	{
		csName = stItem.csName;
		csAuthor = stItem.csAuthor;
		fPrice = stItem.fPrice;
		nVersion = stItem.nVersion;
	}
	S_Book& operator= (const S_Book& stItem)
	{
		if(this == &stItem)
		{
	        return *this;
		}
		//memset(this,0,sizeof(S_Book));
		//memcpy(this,&stItem,sizeof(S_Book));
		    
		csName = stItem.csName;
		csAuthor = stItem.csAuthor;
		fPrice = stItem.fPrice;
		nVersion = stItem.nVersion;
		return *this;
	}
};

基本的结构体能“规范”使用,就再也不用担心更复杂的结构体了。

struct S_Book
{	
    CString csName;
	CString csAuthor;
	float fPrice;
	short int nVersion;
	S_Book()
	{
		Init();
	}
	void Init()
	{
		csName.Empty();
		csAuthor.Empty();
		fPrice = 999999;
		nVersion = 9999;
	}
	S_Book(const S_Book& stItem)
	{
		csName = stItem.csName;
		csAuthor = stItem.csAuthor;
		fPrice = stItem.fPrice;
		nVersion = stItem.nVersion;
	}
	S_Book& operator= (const S_Book& stItem)
	{
		if(this == &stItem)
		{
	        return *this;
		}
		//memset(this,0,sizeof(S_Book));
		//memcpy(this,&stItem,sizeof(S_Book));
		    
		csName = stItem.csName;
		csAuthor = stItem.csAuthor;
		fPrice = stItem.fPrice;
		nVersion = stItem.nVersion;

		return *this;
	}
};
typedef CArray<S_Book,S_Book&>astBook;
struct S_BookInfo
{
	int iNo;
	CString csAddr;
	astBook astBooks;
	S_BookInfo()
	{
		Init();
	}
	void Init()
	{
		iNo = 999999999;
		csAddr.Empty();
		astBooks.RemoveAll();
	}
	S_BookInfo(const S_BookInfo& stItem)
	{
		iNo = stItem.iNo;
		csAddr = stItem.csAddr;
		astBooks.Copy(stItem.astBooks);
	}
	S_BookInfo& operator= (const S_BookInfo& stItem)
	{
		if(this == &stItem)
		{
			return *this;
		}
		iNo = stItem.iNo;
		csAddr = stItem.csAddr;
		astBooks.Copy(stItem.astBooks);
		return *this;
	}
};


int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}
	else
	{
		// TODO: code your application's behavior here.
		astBook astBookAll;
		S_Book S_Book1;
		S_Book1.csAuthor = "Gorden";
		S_Book1.csName = "Easy Python";
		S_Book1.fPrice = 86.9f;
		S_Book1.nVersion = 3;
		cout << "******************** S_Book1 ********************" << endl;
		cout << "Book's Name:" << (LPCTSTR)S_Book1.csName << endl;
		cout << "Author:" << (LPCTSTR)S_Book1.csAuthor << endl;
		cout << "Price:" << S_Book1.fPrice << endl;
		cout << "Version:" << S_Book1.nVersion << endl;
		astBookAll.Add(S_Book1);

		S_Book S_Book2;
		S_Book2 = S_Book1;
		S_Book2.nVersion = 4;
		cout << "******************** S_Book2 ********************" << endl;
        cout << "Book's Name:" << (LPCTSTR)S_Book2.csName << endl;
		cout << "Author:" << (LPCTSTR)S_Book2.csAuthor << endl;
		cout << "Price:" << S_Book2.fPrice << endl;
		cout << "Version:" << S_Book2.nVersion << endl;
		astBookAll.Add(S_Book2);

		S_Book S_Book3;
		S_Book3.csAuthor = "Gorden";
		S_Book3.csName = "Easy C++";
		S_Book3.fPrice = 99.8f;
		S_Book3.nVersion = 7;
		cout << "******************** S_Book3 ********************" << endl;
		cout << "Book's Name:" << (LPCTSTR)S_Book3.csName << endl;
		cout << "Author:" << (LPCTSTR)S_Book3.csAuthor << endl;
		cout << "Price:" << S_Book3.fPrice << endl;
		cout << "Version:" << S_Book3.nVersion << endl;
		astBookAll.Add(S_Book3);
		
		S_BookInfo S_BookInfos;
        S_BookInfos.iNo = 1;
		S_BookInfos.csAddr = "http://book.dangdang.com";
		S_BookInfos.astBooks.Copy(astBookAll);
		cout << "************************ S_BookInfos ************************" << endl;
		cout << "No:" << S_BookInfos.iNo << endl;
		cout << "Addr:" << (LPCTSTR)S_BookInfos.csAddr << endl;
		for(int i = 0; i < S_BookInfos.astBooks.GetSize(); i++)
		{   
			cout <<"========================" << "astBooks" << "[" << i << "]:" << endl;
			cout << "Book's Name:" << (LPCTSTR)S_BookInfos.astBooks[i].csName << endl;
	    	cout << "Author:" << (LPCTSTR)S_BookInfos.astBooks[i].csAuthor << endl;
		    cout << "Price:" << S_BookInfos.astBooks[i].fPrice << endl;
		    cout << "Version:" << S_BookInfos.astBooks[i].nVersion << endl;
		}
		cout << "************************ S_BookInfos ************************" << endl;
	}

	return nRetCode;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值