`
美丽的小岛
  • 浏览: 308164 次
  • 性别: Icon_minigender_1
  • 来自: 大连
社区版块
存档分类
最新评论

C++对象使用错误之复制构造函数与赋值

 
阅读更多

先来一段会出错的代码:

#pragma once

#include <iostream>

class StringBad
{
public:
    StringBad(const char *s);
    StringBad();
    ~StringBad();
    //friend
    friend std::ostream &operator <<(std::ostream &os, const StringBad &st);

private:
    char *str;
    int len;
    static int num_strings;
};

 

#include "StdAfx.h"
#include "StringBad.h"

int StringBad::num_strings = 0;

StringBad::StringBad( const char *s )
{
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    num_strings++;
    std::cout << num_strings << ": \"" << str << "\"object created \n"; 
}

StringBad::StringBad()
{
    len = std::strlen("hello world");
    str = new char[len + 1];
    std::strcpy(str, "hello world");
    num_strings++;
    std::cout << num_strings << ": \"" << str << "\"object created \n"; 
}

StringBad::~StringBad()
{
    std::cout << "\"" << str << "\" object delete, ";
    --num_strings;
    std::cout << num_strings << " left\n";
    delete []str; 
}

std::ostream & operator<<( std::ostream &os, const StringBad &st )
{
    os << st.str;
    return os;
}

 

// TestObjectThink.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include "StringBad.h"

using std::cout;
using std::endl;

void callMe1(StringBad &rsb)
{
    cout << "reference" << endl;
    cout << "\"" << rsb << "\"" << endl;
}

void callMe2(StringBad rsb)
{
    cout << "value" << endl;
    cout << "\"" << rsb << "\"" << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    {
        cout << "Starting an inner block \n";
        StringBad hello01("hello_01");
        StringBad hello02("hello_02");
        StringBad hello03("hello_03");

        cout << "hello01: " << hello01 << endl;
        cout << "hello02: " << hello02 << endl;
        cout << "hello03: " << hello03 << endl;    

        callMe1(hello01);
        cout << "hello01: " << hello01 << endl;
        callMe2(hello02);
        cout << "hello02: " << hello02 << endl;
        
        //等效于StringBad hello01Temp = StringBad(hello01);
        //新建一个对象并将其初始化为同类现有对象时,会调用复制构造函数。
        StringBad hello01Temp = hello01;
        cout << "hello01Temp:" << hello01Temp << endl;

        StringBad hello03Temp;
        hello03Temp = hello03;
        cout << "hello03Temp:" << hello03Temp << endl;
    
        //system("pause");
    }
	return 0;
}

 callMe2()调用完数据出错了,最后在对象释放时出现了崩溃性的错误,解决方法,加入下面两个函数。

StringBad::StringBad( const StringBad &st )
{
    num_strings++;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
    std::cout << num_strings << ": \"" << str << "\"object created(copy) \n"; 
}

StringBad & StringBad::operator=( const StringBad &st )
{
    if (this == &st)
    {
        return *this;
    }
    delete []str;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
    std::cout << num_strings << ": \"" << str << "\"(assign) \n"; 
    return *this;
}

  
 

有空了再加上原因, 想急切了解的,参考:C++ primer plus(第六版) P425

 

  • 大小: 165.1 KB
分享到:
评论

相关推荐

    没有可用的复制构造函数或复制构造函数声明

    在C++编程中,"没有可用的复制构造函数或复制构造函数声明"是一个常见的错误,通常出现在尝试复制一个对象,而该对象的类没有定义复制构造函数时。在这个特定的情境中,问题出在一个名为`CArray, int&gt;`的自定义数组...

    C++复制构造函数详解

    此外,复制构造函数与默认构造函数、析构函数和赋值运算符一起构成了C++的特殊成员函数,这些函数对对象生命周期的管理起着关键作用。熟练掌握这些函数的使用,能够帮助开发者编写出更加安全、可维护的代码。

    详解C++ 拷贝构造函数和赋值运算符

    在C++编程中,拷贝构造函数和赋值运算符是两种重要的成员函数,它们用于处理对象间的值复制。这篇文章将深入探讨这两种机制的区别、调用条件以及深拷贝和浅拷贝的概念。 拷贝构造函数是一种特殊的构造函数,它接受...

    C++实现 类string的 普通构造函数, 拷贝构造函数 析构函数 和赋值函数

    了解这些基本的构造函数和赋值运算符对于理解C++对象的生命周期和行为至关重要。在实际编程中,这些函数的正确实现可以确保代码的稳定性和效率,同时避免内存泄漏和其他潜在错误。通过自定义`std::string`类的构造...

    c++构造函数小测验

    Sprite类还包含了一个复制构造函数和一个赋值运算符重载,这在C++中用于支持复制语义,确保对象复制的正确性。赋值运算符重载在复制对象时被调用,用于处理对象之间的赋值操作,其目的是避免浅拷贝带来的问题,确保...

    拷贝构造函数和赋值运算符的区别 (2).docx

    在C++编程中,拷贝构造函数和赋值运算符是两个至关重要的概念,它们都是处理对象间的复制行为,但有着明显的区别和各自的应用场景。 **拷贝构造函数** 拷贝构造函数是一种特殊的构造函数,它的主要任务是在创建新...

    C++中复制构造函数与重载赋值操作符的深入分析

    如果基类没有合适的复制构造函数和赋值操作符,那么派生类对象的正确复制和赋值就无法保证,可能导致数据丢失或错误行为。 总结来说,复制构造函数和重载赋值操作符在C++中扮演着至关重要的角色,它们确保了对象...

    拷贝构造函数和赋值运算符的区别 (2).pdf

    在编程领域,特别是C++语言中,理解和正确使用拷贝构造函数和赋值运算符是非常重要的概念。这两个机制都是处理对象复制的过程,但它们在使用场景和行为上有所区别。 首先,构造函数是用于初始化新创建的对象的特殊...

    高质量C++C编程指南 - 第9章 类的构造函数、析构函数与赋值函数.docx

    在C++编程中,类的构造函数、析构函数和赋值函数是至关重要的成员函数,它们负责对象的创建、初始化、复制以及销毁。这些函数虽然看似基础,但其作用和设计背后的深思熟虑不容忽视。本章将深入探讨这些函数的原理和...

    C++中复制构造函数和重载赋值操作符总结

    C++中的复制构造函数和重载赋值操作符是编程中至关重要的概念,尤其是在处理对象的复制和赋值时。这两个特殊成员函数确保了对象之间的数据安全和正确性。 复制构造函数是一种特殊的构造函数,其任务是初始化一个新...

    example2_24.rar_C++ 对象 复制

    标题“example2_24.rar_C++ 对象 复制”表明我们将探讨的是C++中的对象复制机制,这通常涉及到复制构造函数和赋值运算符。 复制构造函数是一种特殊的构造函数,它的任务是创建一个新对象作为现有对象的副本。描述中...

    拷贝构造函数和赋值操作符号的重载.docx

    总结来说,拷贝构造函数和赋值操作符重载是C++中处理对象复制和赋值的核心机制,尤其在处理动态内存分配的类时。它们保证了对象间的独立性,防止数据损坏和内存泄漏。为包含动态资源的类提供这两个功能是良好编程...

    c++构造函数实例质料

    在C++编程语言中,构造函数是类的一个特殊成员函数,它的主要作用是初始化新创建的对象。构造函数的名称与类名相同,且没有返回类型。在这个实例中,我们看到了两种不同类型的构造函数:无参数构造函数和带有参数的...

    详谈C++何时需要定义赋值/复制构造函数

    在C++编程语言中,定义赋值和复制构造函数是至关重要的,因为它们控制着对象的创建、复制以及赋值过程。本文将详细讨论何时需要自定义这些特殊成员函数。 1. **默认构造函数**: 默认构造函数是在没有参数或者所有...

    拷贝构造函数和赋值运算符的区别.pdf

    例如,如果一个类对象包含指向动态分配内存的指针,如`CExample`类所示,那么默认的拷贝构造函数只会复制指针,而不是指针指向的数据,导致两个对象共享同一内存,这在多线程或对象生命周期管理中可能引发错误。...

    第9章类的构造函数、析构函数与赋值函数[文].pdf

    总的来说,理解和正确使用构造函数、析构函数、拷贝构造函数和赋值函数是C++编程中至关重要的技能,它们有助于确保对象的正确初始化和清理,以及在对象复制和赋值时保持数据的一致性和完整性。忽视这些函数的细节...

    拷贝构造函数和赋值操作符号的重载.pdf

    在C++编程中,拷贝构造函数和赋值操作符重载是两个非常重要的概念,尤其是在处理包含动态分配内存的类时。拷贝构造函数和赋值操作符的正确实现对于确保对象之间的独立性和防止资源泄露至关重要。 拷贝构造函数是一...

    c++类构造函数详解_.docx

    复制构造函数接收一个同类型的对象引用作为参数,用于创建新对象时复制已有对象的状态。在默认情况下,复制构造函数会按成员逐个复制,但如果类中包含动态分配的内存(即指针成员),默认的复制构造函数可能导致浅...

    深入C++中构造函数、拷贝构造函数、赋值操作符、析构函数的调用过程总结

    C++中的构造函数、拷贝构造函数、赋值操作符和析构函数是面向对象编程中的核心概念,它们在对象的生命周期中起着至关重要的作用。下面是对这些函数的详细解释和调用过程的总结: 1. **构造函数**: - 构造函数是一...

    详解C++ 编写String 的构造函数、拷贝构造函数、析构函数和赋值函数

    在C++编程中,正确地管理类的构造函数、拷贝构造函数、析构函数和赋值函数是创建健壮、无内存泄漏程序的关键。接下来将详细介绍如何为自定义的String类编写这些函数,并通过实例来加深理解。 首先,我们定义一个...

Global site tag (gtag.js) - Google Analytics