IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++翁恺学习24-拷贝构造2 -> 正文阅读

[C++知识库]C++翁恺学习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没有拷贝构造,所有对象的传递都是通过指针。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 18:17:37  更:2022-04-22 18:19:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 21:51:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码