【翁恺】24-拷贝构造2

如果类包含指针?

Copy pointer:

#ifndef PERSON_H_
#define PERSON_H_
class Person
{
public:
	Person(const char* s);//构造函数
	~Person();//析构函数
	void print();//函数原型,没有实际body,有一些什么样的函数
	//...
//private:
	char* name ;//数据成员 char* instead of string
	//...
};
#endif // !PERSON_H_
 
//person.h
#include "person.h"
#include<iostream>
#include<string.h>
using namespace std;
 
//在.cpp文件中定义在.h文件中声明的那些东西的实体
Person::Person(const char* s)
{
	name = new char[::strlen(s)+1];
	::strcpy(name,s);
}
Person::~Person()
{
	//delete[] name;
}
 
void Person::print()
{
	cout << "something" << endl;
}
//person.cpp
#include<stdio.h>
#include "person.h"
using namespace std;
 
int main()
{
	Person p1("Jhon");
	Person p2 = p1; //Person p2(p1);
	printf("p1.name=%p\n", p1.name);  // p1 name 的地址
	printf("p2.name=%p\n", p2.name);
	return 0;
}
//main.cpp

 

 地址一样,报错原因:指向同一块内存,被析构了两次。

p1 和 p2 指向同一块内存,即 Copy pointer,而我们想要 Copy entire block。 

 character strings

  • in c++,a character string is
    • an array of characters
    • with a special terminator--"\0" or ASCII null
  • the string "c++" is represented,in memory,by an array of four (4,count'em) characters

C的字符串:

 standard c library string functions

  • declared in <string>

    size_t strlen(const char *s);
    • s is a null-terminated string
    • returns the length of s
    • length does not include the terminator!
    char *strcpy (char *dest,const char *src);
    • copies src to dest stopping after the terminating null-character is copied
    • dest should have enough memory space allocated to contain src string

 Copy entire block :

#ifndef PERSON_H_
#define PERSON_H_
class Person
{
public:
	Person(const char* s);//构造函数
	Person(const Person& w);//拷贝构造函数
	~Person();//析构函数
	void print();//函数原型,没有实际body,有一些什么样的函数
	//...
//private:
	char* name ;//数据成员 char* instead of string
	//...
};
#endif // !PERSON_H_
//person.h
#include "person.h"
#include<iostream>
#include<string.h>
using namespace std;
 
//在.cpp文件中定义在.h文件中声明的那些东西的实体
Person::Person(const char* s)
{
	name = new char[::strlen(s)+1];
	::strcpy(name,s);
}
Person::Person(const Person& w)
{
	name = new char[::strlen(w.name) + 1];
	::strcpy(name, w.name);
}
Person::~Person()
{
	//delete[] name;
}
 
void Person::print()
{
	cout << "something" << endl;
}
//person.cpp
#include<stdio.h>
#include "person.h"
using namespace std;
 
int main()
{
	Person p1("Jhon");
	Person p2 = p1;//Person p2(p1);
	printf("p1.name=%p\n", p1.name);
	printf("p2.name=%p\n", p2.name);
	return 0;
}
//main.cpp

private 是针对类而不是对象。所以访问一个同类对象的private 东西是可以的。

Person(char*) implementation

#inlcude <cstring>
ussing namespace std;

Person::Person(const char *s){
    name = new char[::strenlen(s)+1];
    ::strcpy(name,s);
}

Person::~Person(){
    delete [] name;//array delete
}

Person copy constructor

  • to Person declaration add copy constructor prototype

    Person(const Person& w);//copy ctor
  • to Person .cpp add copy ctor definition

    Person::Person char(const Person& w){
        name = char[::strlen(w.name)+1];
        ::strcpy(name,w.name);
    }
  • no value return

  • accesses "w.name" across client boundary

  • the copy ctor initializes uninitialized memory

使用类的一个对象来构造另一个该类的新的对象。

when are copy constructor called?

什么时候发生拷贝构造:初始化的时候。 

什么时候调用拷贝构造

1. 调用函数时候,函数参数是一个对象本身,而不是引用或者指针的时候,隐藏调用。函数参数是一个对象本身意味着调用该函数时候,调用时候重新创建一个新的Person类的对象player,就会发生拷贝构造,因为使用某个对象初始化这个player。

  • during call by value  隐藏调用

    void roster(Person);//declare function
    Person child("Ruby");//create object
    roster(child);//call function

  • during initialization 2.初始化时。 直接调用

    Person baby_a("Fred");
    //these use the copy ctor
    Person baby_b = baby_a;//not an assignment
    Person baby_c(baby_a);//not an assignment

 习惯:接受()初始化。

  • during function return    3.函数返回一个对象时。

    Person captain(){
        Person player("George");
        return player;
    }
    ...
    Person who("")
    ...

copies and overhead

  • compilers can "optimize out" copies when safe  把拷贝构造优化掉
  • programmers need to
    • program for "dumb" compilers
    • be ready to look for optimizations

example

Person copy_func(char *who){
    Person local(who);
    local.print();
    return local;//copy ctor called
}

Person nocopy_func(char *who){
    return Peron(who);
    //no copy needed  优化掉
}

construction vs. assignment

  • every object is constructed once
  • every object should be destroyed once
    • failure to invoke delete()
    • invoking delete() more than once
  • once an object is constructed,it can be the target of many assignment operations

Person:string name

string 类的变量不用写 拷贝构造,内部实现好了。所以C++尽量用string 放弃 char*。使用 char* 只有 直接访问内存,做的是二进制数据。给人读的字符串就应该使用 string。

  • what if the name was a string (and not a char*)

    #include <string>
    class Person{
    public:
        Person(const string&);
        ~Person();
        void print();
        //...other accessor fxns
    private:
        string name;//embedded object(composition)
        //...other data members
    };
  • in the default ctor ,the compiler recursively calls the copy ctors for all member objects(and base classes)

  • default is memberwise initialization

copy ctor guidelines

  • in general,be explicit
    • create your own copy ctor--don't rely on the default
  • if you don't need on declare a private copy ctor
    • prevents creation of a a default copy constructor
    • generates a compiler error if try to pass-by -value
    • don't need a definition

一旦写一个类就写下:

default constructor  

virtual constructor  

copy constructor

拷贝构造是私有的,别人就不能拷贝构造你的对象了,即别人设计一个函数,函数的参数不能是你的类的对象的本身* 和 & 还是可以的。 

不建议拷贝构造是私有的。JAVA没有拷贝构造,所有对象的传递都是通过指针。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

理心炼丹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值