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把对象比作电视机,把引用比作遥控器,我觉得很恰当:
上面的程序中,jc和jc2某一时刻都指向统一个对象,但随后jc2指向了新的一个对象,所以输出不一样;
jc3和jc4都指向同一个对象,而且通过jc4作为桥梁修改了这个对象的值,当然jc3所指向的对象也就变了,所以输出一样;
通过jc5我们可以知道两件事,第一件是对象初始类型为null(C++对象没有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++拷贝构造函数(深拷贝,浅拷贝)详解.pdf
本文主要介绍了拷贝构造函数和赋值运算符的区别,以及在什么时候调用拷贝构造函数、什么情况下调用赋值运算符。最后,简单的分析了下深拷贝和浅拷贝的问题。有需要的朋友可以看下
1、本文详细描述了C++语言拷贝构造函数的用法。 2、通过详细示例,让读者更直观地阅读,更清晰的理解。 3、示例代码可直接复制,编译后可直接运行。 4、根据示例以及运行结果,让读者加强记忆及理解。
初学者入门实例,看懂后,初学者能够对拷贝构造函数有一个清楚的了解,这是我自己的经验哈
C++类对象的拷贝构造函数 C++类对象的拷贝构造函数 C++类对象的拷贝构造函数 C++类对象的拷贝构造函数 C++类对象的拷贝构造函数 C++类对象的拷贝构造函数
C++规定与类同名的函数就是拷贝构造函数 默认拷贝构造函数 在类定义中如果没有提供自己的拷贝构造函数,则C++提供一个默认的构造函数,其拷贝策略是逐个成员依次拷贝。 深拷贝和浅拷贝 默认拷贝构造函数均是浅拷贝 ...
1. 对象以值传递的方式传入函数参数[c-sharp] view plaincopyclass CExample { private: int a 2
1.什么是拷贝构造函数: 拷贝构造函数嘛,当然就是拷贝和构造了。(其实很多名字,只要静下心来想一想,就真的是顾名思义呀)拷贝又称复制,因此拷贝构造函数又称复制构造函数。百度百科上是这样说的:拷贝构造函数...
C++中一般创建对象,拷贝或赋值的方式有构造函数,拷贝构造函数,赋值函数这三种方法。下面就详细比较下三者之间的区别以及它们的具体实现 1.构造函数 构造函数是一种特殊的类成员函数,是当创建一个类的对象时,它...
拷贝构造函数是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++拷贝构造函数和关键字explicit的相关知识,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
C++ 拷贝构造函数 double*指针成员
本资源通过代码实例详细介绍在C++程序中调用拷贝构造函数的三种情境,每行代码配有详细的注释,帮助学习者直观理解
C++复制构造函数详解C++复制构造函数详解C++复制构造函数详解C++复制构造函数详解C++复制构造函数详解