栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++类的拷贝控制

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++类的拷贝控制

 定义行为像指针的类,当对类进行复制时对类成员变量进行引用

#include 

class HasPtr
{
public:
	
	HasPtr(const std::string& s = std::string()): ps(new std::string(s)), i(0), use(new std::size_t(1)) {};
	// 拷贝构造函数
	HasPtr(HasPtr& p) : ps(p.ps), i(p.i), use(p.use)
	{
		++* use;
		std::cout << "copy constructor" << std::endl;
	};
	// 拷贝赋值运算符
	HasPtr& operator=(const HasPtr&);
	// 析构函数
	~HasPtr();
private:
	
	friend void swap(HasPtr& lhs, HasPtr& rhs);
	std::string* ps;
	int i;
	std::size_t* use;
};

HasPtr::~HasPtr()
{
	std::cout << "destroyed" << std::endl;
	if (--*use == 0)
	{
		std::cout << "released" << std::endl;
		delete ps;
		delete use;
	}
}

inline void swap(HasPtr& lhs, HasPtr& rhs)
{
	using std::swap;
	swap(lhs.ps, rhs.ps); // 这里交换的是两个对象的地址而不是值
	swap(lhs.i, rhs.i);
}



HasPtr& HasPtr::operator=(const HasPtr& rhs)
{
	std::cout << "use operater copy." << std::endl;
	// 先递增右侧运算对象的引用计数,再递减本对象的引用计数,用于处理自赋值
	++*rhs.use;
	// 当左值对象没有引用的时候,释放左值对象内存
	if (--*use == 0)
	{
		std::cout << "realse left hand side value." << std::endl;
		delete ps;
		delete use;
	}
	ps = rhs.ps;
	i = rhs.i;
	use = rhs.use;
	return *this;
}


int main()
{
	
	{
		HasPtr p1 = { "zhang" };
		HasPtr p2 = {"san"};

		swap(p1, p2);

		p2 = p1;
		HasPtr p3 = p1;
	}
	std::cout << "over" << std::endl;
	std::cin.get();
	return 0;
}

拷贝控制的示例

 

#include 
#include 

class Folder;

class Message
{
    friend void swap(Message&, Message&);
    friend void swap(Folder&, Folder&);
    friend class Folder;
public:
    explicit Message(const std::string& str = "") : contents(str) { }
    Message(const Message&);
    Message& operator=(const Message&);
    Message(Message&& m); // need to update the Folders
    Message& operator=(Message&&); // need to update the Folders
    ~Message();

    void save(Folder&);
    void remove(Folder&);

    const std::string& msg() const { return contents; }
    void print_debug();

private:
    void add_to_Folders(const Message&);
    void remove_from_Folders();

    void addFldr(Folder* f) { folders.insert(f); }
    void remFldr(Folder* f) { folders.erase(f); }

    void move_Folders(Message*); // define function to do the common work

private:
    std::string contents;
    std::set folders;
};

void swap(Message&, Message&);

class Folder {
    friend void swap(Message&, Message&);
    friend void swap(Folder&, Folder&);
    friend class Message;
public:
    explicit Folder(const std::string& str = "") :name(str) { }
    Folder(const Folder&);
    Folder& operator=(const Folder&);
    Folder(Folder&& f); // need to update the Messages
    Folder& operator=(Folder&&); // need to update the Messages
    ~Folder();

    const std::string& fldr() const { return name; }
    void print_debug();

private:
    std::string name;
    std::set msgs;

    void add_to_Message(const Folder&);
    void remove_from_Message();

    void addMsg(Message* m) { msgs.insert(m); }
    void remMsg(Message* m) { msgs.erase(m); }

    void move_Messages(Folder*); // define function to do the common work
};

void swap(Folder&, Folder&);

void swap(Message& lhs, Message& rhs)
{
    using std::swap;
    for (auto f : lhs.folders)
        f->remMsg(&lhs);
    std::cout << "Remove message from folders" << std::endl; // debug

    for (auto f : rhs.folders)
        f->remMsg(&rhs);
    std::cout << "Remove message from folders" << std::endl; // debug

    swap(lhs.folders, rhs.folders);
    swap(lhs.contents, rhs.contents);

    std::cout << "Message members swaped" << std::endl; // debug

    for (auto f : lhs.folders)
        f->addMsg(&lhs);
    std::cout << "Added message to folders" << std::endl; // debug

    for (auto f : rhs.folders)
        f->addMsg(&rhs);
    std::cout << "Added message to folders" << std::endl; // debug
}

Message::Message(const Message& m) : contents(m.contents), folders(m.folders)
{
    add_to_Folders(m);
}

Message::~Message()
{
    remove_from_Folders();
}

void Message::save(Folder& f)
{
    folders.insert(&f);
    f.addMsg(this);
}

void Message::remove(Folder& f)
{
    folders.erase(&f);
    f.remMsg(this);
}

void Message::add_to_Folders(const Message& m)
{
    for (auto f : m.folders)
        f->addMsg(this);
    std::cout << "Added message to folders" << std::endl; // debug
}

void Message::remove_from_Folders()
{
    for (auto f : folders)
        f->remMsg(this);
    std::cout << "Remove message from folders" << std::endl; // debug
}

Message& Message::operator=(const Message& rhs)
{
    remove_from_Folders();
    contents = rhs.contents;
    folders = rhs.folders;
    std::cout << "Message members assgined" << std::endl; // debug
    add_to_Folders(rhs);
    return *this;
}

void Message::print_debug()
{
    std::cout << contents << ": ";
    for (auto f : folders)
        std::cout << f->fldr() << " ";
    std::cout << std::endl;
}

void Message::move_Folders(Message* m)
{
    folders = std::move(m->folders);
    for (auto f : folders)
    {
        f->remMsg(m);
        f->addMsg(this);
    }
    m->folders.clear();
}

Message::Message(Message&& m) : contents(std::move(m.contents))
{
    move_Folders(&m);
}

Message& Message::operator= (Message&& rhs)
{
    if (this != &rhs)
    {
        remove_from_Folders();
        contents = std::move(rhs.contents);
        move_Folders(&rhs);
    }
    std::cout << "Message members moved" << std::endl; // debug
    return *this;
}

// Folder Implementation

void swap(Folder& lhs, Folder& rhs)
{
    using std::swap;
    for (auto m : lhs.msgs)
        m->remFldr(&lhs);
    std::cout << "clear folder" << std::endl; // debug

    for (auto m : rhs.msgs)
        m->remFldr(&rhs);
    std::cout << "clear folder" << std::endl; // debug

    swap(lhs.name, rhs.name);
    swap(lhs.msgs, rhs.msgs);
    std::cout << "Folder members swaped" << std::endl; // debug

    for (auto m : lhs.msgs)
        m->addFldr(&lhs);
    std::cout << "Added messages to folder" << std::endl; // debug

    for (auto m : rhs.msgs)
        m->addFldr(&rhs);
    std::cout << "Added messages to folder" << std::endl; // debug
}

void Folder::add_to_Message(const Folder& f)
{
    for (auto m : f.msgs)
        m->addFldr(this);
    std::cout << "Added messages to folder" << std::endl; // debug
}

Folder::Folder(const Folder& f) : name(f.name), msgs(f.msgs)
{
    add_to_Message(f);
}

void Folder::remove_from_Message()
{
    for (auto m : msgs)
        m->remFldr(this);
    std::cout << "clear folder" << std::endl; // debug
}

Folder::~Folder()
{
    remove_from_Message();
}

Folder& Folder::operator =(const Folder& rhs)
{
    remove_from_Message();
    name = rhs.name;
    msgs = rhs.msgs;
    std::cout << "Folder members assigned" << std::endl; // debug
    add_to_Message(rhs);
    return *this;
}

void Folder::print_debug()
{
    std::cout << name << ": ";
    for (auto m : msgs)
        std::cout << m->msg() << " ";
    std::cout << std::endl;
}

void Folder::move_Messages(Folder* f)
{
    msgs = std::move(f->msgs);
    for (auto m : msgs)
    {
        m->remFldr(f);
        m->addFldr(this);
    }
    f->msgs.clear();
}

Folder::Folder(Folder&& f) : name(std::move(f.name))
{
    move_Messages(&f);
}

Folder& Folder::operator=(Folder&& rhs)
{
    if (this != &rhs)
    {
        remove_from_Message();
        name = std::move(rhs.name);
        move_Messages(&rhs);
    }
    std::cout << "Message members moved" << std::endl; // debug
    return *this;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/983547.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号