`
cantellow
  • 浏览: 842610 次
  • 性别: Icon_minigender_1
  • 来自: 草帽海贼团
社区版块
存档分类
最新评论

C++的拷贝构造函数

    博客分类:
  • C++
 
阅读更多

 

package com.cantellow.test;

import java.util.Vector;

public class Test {

    public static void main(final String[] args) {
        final String a = "2";
        String b = a;
        b = "7";
        System.out.println(a);
        System.out.println(b);

        final JavaClass jc = new JavaClass("qqqqqq");
        JavaClass jc2 = jc;
        jc2 = new JavaClass("wwwwwwwwww");
        System.out.println(jc);
        System.out.println(jc2);

        final JavaClass jc3 = new JavaClass("rrrrrrrrr");
        final JavaClass jc4 = jc3;
        jc4.setS("tttttt");
        System.out.println(jc3);
        System.out.println(jc4);

        final JavaClass jc5 = new JavaClass("test vector");
        System.out.println(jc5.getVs());
        jc5.setVs(new Vector<String>());
        jc5.getVs().add("v1");
        System.out.println(jc5.getVs());
    }
}

class JavaClass {

    private String s;

    private Vector<String> vs;

    public JavaClass(final String s) {
        this.s = s;
    }

    public synchronized String getS() {
        return s;
    }

    public synchronized void setS(final String s) {
        this.s = s;
    }

    public synchronized Vector<String> getVs() {
        return vs;
    }

    public synchronized void setVs(final Vector<String> vs) {
        this.vs = vs;
    }

    @Override
    public String toString() {
        return s;
    }

}

 java的类型系统,java除了几个基本类型之外,并没有引用和指针的区分,并不像C++一样,加上&*就是一种新的类型,而且java的基本类型都是值传递和赋值,非基本类型则是引用传递,但string比较特殊,因为其本身的实现,看起来它的行为基本类型表现一样。

java很简单,所有的对象都必须在堆上new(而不是C++还要区分栈对象和堆对象),我们不能直接操作这些对象,必须通过引用来达到目的,我记得think in java把对象比作电视机,把引用比作遥控器,我觉得很恰当:

上面的程序中,jcjc2某一时刻都指向统一个对象,但随后jc2指向了新的一个对象,所以输出不一样;

jc3jc4都指向同一个对象,而且通过jc4作为桥梁修改了这个对象的值,当然jc3所指向的对象也就变了,所以输出一样;

通过jc5我们可以知道两件事,第一件是对象初始类型为nullC++对象没有null概念,只有指针有),第二件就是java中的参数传递确实是引用传递。

 

 

#ifndef CPP_CLASS_H
#define CPP_CLASS_H
#include <string>
#include <vector>
#include <iostream>
using std::string;
using std::cout;
using std::endl;
class Object{
public:
	int i;
	Object(int i){
		this->i = i;
	}

	/*Object& operator=(const Object& t1){
		i = t1.i;
		return *this;
	}
	Object(const Object& o){
		this->i = o.i;
	}*/
};
class CPPClass{
public:
	CPPClass():o(1),s("ss"),vs(){
		
	}
	Object GetO() const { return o; }

	void SetO(Object val) { o = val; }

	string GetS() const { return s; }

	void SetS(string val) { s = val; }

	std::vector<string> GetVs() const { return vs; }

	void SetVs(std::vector<string> val) { vs = val; }

	Object o;
	string s;
	std::vector<string> vs;
private:

};
#endif

 main函数中:

 

#include "CPPClass.h"

int main(){
	CPPClass cpp;
	cout << &cpp.s << " " << &cpp.GetS() << endl;
	cout << &cpp.o << " " << &cpp.GetO() << endl;
	cout << &cpp.vs << " " << &cpp.GetVs() << endl;
}

 输出:

 

0018FEE8 0018FEC0

0018FEE4 0018FEBC

0018FF08 0018FEA8

 

要是在返回的类型前面加&,如下:

 

Object& GetO() { return o; }
string& GetS() { return s; }
std::vector<string>& GetVs() { return vs; }

 输出:

 

0018FEE8 0018FEE8

0018FEE4 0018FEE4

0018FF08 0018FF08

 

这表明加上&才是真正的返回对象里面的成员,那如果不加&就返回了一个新的对象,那这到底发生什么了呢?

实际上程序临时生成了一个对象,这个对象是通过拷贝构造函数生成的,我们再来看一下参数传递会发生什么事情:

 

        string s2;
	Object o2(7);
	std::vector<string> vs2;
	cpp.SetS(s2);
	cpp.SetO(o2);
	cpp.SetVs(vs2);

	cout << &s2 << " " <<  &cpp.s << endl;
	cout << &o2 << " " << &cpp.o << endl;
	cout << &vs2 << " " << &cpp.vs << endl;

 输出:

 

0018FEBC 0018FEE8

0018FEB0 0018FEE4

0018FE94 0018FF08

如果我们同样按照上次的方法将参数传递加一个&,会发生什么呢?

 

        void SetO(Object& val) { o = val; }
	void SetS(string& val) { s = val; }
	void SetVs(std::vector<string>& val) { vs = val; }

 输出:

 

0018FEBC 0018FEE8

0018FEB0 0018FEE4

0018FE94 0018FF08

并不像我们想的那样是一个地址,也就是他们不是同一个对象,那到底问题出在哪?

所有的这一切,牵涉除了两个概念:拷贝构造函数和操作符重载。

http://blog.csdn.net/lwbeyond/article/details/6202256

http://www.vckbase.com/index.php/wv/584

分享到:
评论

相关推荐

    C++ 拷贝构造函数 赋值构造函数

    C++ 拷贝构造函数 赋值构造函数 解释

    C++拷贝构造函数和赋值操作

    C++拷贝构造函数和赋值操作 拷贝构造函数对同一个对象来说只会调用一次,而且是在对象构造时调用。此时对象本身还没有构造,无需要去释放自己的一些资源。而赋值操作可能会调用多次,你在拷贝之前要释放自己的一些...

    C++简单类(构造函数,析构函数以及拷贝构造函数)的实现

    C++简单类的实现,包括构造函数,析构函数以及拷贝构造函数

    详解C++ 拷贝构造函数

    拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于: 通过使用另一个同类型的对象来初始化新创建的对象。 复制对象把它作为参数传递给...

    c++拷贝构造函数(深拷贝,浅拷贝)详解.pdf

    c++拷贝构造函数(深拷贝,浅拷贝)详解.pdf

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

    本文主要介绍了拷贝构造函数和赋值运算符的区别,以及在什么时候调用拷贝构造函数、什么情况下调用赋值运算符。最后,简单的分析了下深拷贝和浅拷贝的问题。有需要的朋友可以看下

    C++拷贝构造函数的介绍及使用

    1、本文详细描述了C++语言拷贝构造函数的用法。 2、通过详细示例,让读者更直观地阅读,更清晰的理解。 3、示例代码可直接复制,编译后可直接运行。 4、根据示例以及运行结果,让读者加强记忆及理解。

    c++中拷贝构造函数实例

    初学者入门实例,看懂后,初学者能够对拷贝构造函数有一个清楚的了解,这是我自己的经验哈

    C++类对象的拷贝构造函数

    C++类对象的拷贝构造函数 C++类对象的拷贝构造函数 C++类对象的拷贝构造函数 C++类对象的拷贝构造函数 C++类对象的拷贝构造函数 C++类对象的拷贝构造函数

    C++规定与类同名的函数就是拷贝构造函数

    C++规定与类同名的函数就是拷贝构造函数 默认拷贝构造函数 在类定义中如果没有提供自己的拷贝构造函数,则C++提供一个默认的构造函数,其拷贝策略是逐个成员依次拷贝。 深拷贝和浅拷贝 默认拷贝构造函数均是浅拷贝 ...

    C++拷贝构造函数详解1

    1. 对象以值传递的方式传入函数参数[c-sharp] view plaincopyclass CExample { private: int a 2

    C++中拷贝构造函数的总结详解

    1.什么是拷贝构造函数: 拷贝构造函数嘛,当然就是拷贝和构造了。(其实很多名字,只要静下心来想一想,就真的是顾名思义呀)拷贝又称复制,因此拷贝构造函数又称复制构造函数。百度百科上是这样说的:拷贝构造函数...

    详解C++中构造函数,拷贝构造函数和赋值函数的区别和实现

    C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法。下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函数 构造函数是一种特殊的类成员函数,是当创建一个类的对象时,它...

    深入C++拷贝构造函数的总结详解

    拷贝构造函数是C++最基础的概念之一,大家自认为对拷贝构造函数了解么?请大家先回答一下三个问题:1. 以下函数哪个是拷贝构造函数,为什么?X::X(const X&); X::X(X); X::X(X&, int a=1); X::X(X&, int a=1, b=2);...

    c++之十引用和拷贝构造函数

    c++之十引用和拷贝构造函数c++之十引用和拷贝构造函数c++之十引用和拷贝构造函数c++之十引用和拷贝构造函数

    c/c++拷贝构造函数和关键字explicit详解

    主要介绍了c/c++拷贝构造函数和关键字explicit的相关知识,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

    double*成员及拷贝构造函数使用

    C++ 拷贝构造函数 double*指针成员

    拷贝构造函数.rar

    本资源通过代码实例详细介绍在C++程序中调用拷贝构造函数的三种情境,每行代码配有详细的注释,帮助学习者直观理解

    C++复制构造函数详解

    C++复制构造函数详解C++复制构造函数详解C++复制构造函数详解C++复制构造函数详解C++复制构造函数详解

Global site tag (gtag.js) - Google Analytics