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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值