引用和拷贝构造函数
在C++中,引用是支持运算符重载语法的基础。引用就像是自动地被编译器间接引用的常量型指针。
引用介绍
http://blog.163.com/zhoumhan_0351/blog/static/39954227200932753054227
指针和引用
http://blog.163.com/zhoumhan_0351/blog/static/39954227200991493418747
1、引用
void f(int&) {}
void g(const int&) {}
int main() {
int a=1;
f(1); // Error
f(a);
g(1);
} ///:~
如上程序所示,由于临时变量总是const类型的,所以将函数的参数定义为常引用是很重要的(当然视情况而定)。
//: C11:Reference.cpp
// Simple C++ references
int* f(int* x) {
(*x)++;
return x; // Safe, x is outside this scope
}
int& g(int& x) {
x++; // Same effect as in f()
return x; // Safe, outside this scope
}
int main() {
int a = 0;
f(&a); // Ugly (but explicit)
g(a); // Clean (but hidden)
} ///:~
2、指针引用
//: C11:ReferenceToPointer.cpp
#include <iostream>
using namespace std;
void increment(int*& i) { i++; }
int main() {
int* i = 0;
cout << "i = " << i << endl;
increment(i);
cout << "i = " << i << endl;
} ///:~是指针变化,而不是所指向的值
3、拷贝构造函数
http://blog.163.com/zhoumhan_0351/blog/static/3995422720100250413207
在C++中,参数是从右向左进栈的。重入意味着任何函数可以中断任何其他函数。
形式:X(X&)
编译器获得一个拷贝构造函数的过程称为成员方法初始化。仅当准备按值传递的方法传递类对象时,才需要拷贝构造函数。
对 于一个类X,如果一个构造函数的第一个参数是下列之一:
a) X&
b) const X&
c) volatile X&
d) const volatile X&
且没有其他参数或其他参数都有默认值,那么这个函数是拷贝构造函数;类中可以存在超过一个拷贝构造函数。默认的参数可能为X::X(const X&)或X::X(X&),拷贝构造函数不能由成员函数模版生成。构造函数不能声明为虚函数,析构函数可以声明为虚函数。
//: C11:HowMany2.cpp
// The copy-constructor
#include <fstream>
#include <string>
using namespace std;
ofstream out("C:\\HowMany2.out");
class HowMany2 {
string name; // Object identifier
static int objectCount;
public:
HowMany2(const string& id = "") : name(id) {
++objectCount;
print("HowMany2()");
}
~HowMany2() {
--objectCount;
print("~HowMany2()");
}
// The copy-constructor:
HowMany2(const HowMany2& h) : name(h.name) {
name += " copy";
++objectCount;
print("HowMany2(const HowMany2&)");
}
void print(const string& msg = "") const {
if(msg.size() != 0)
out << msg << endl;
out << '\t' << name << ": "
<< "objectCount = "
<< objectCount << endl;
}
};
int HowMany2::objectCount = 0;
// Pass and return BY VALUE:
HowMany2 f(HowMany2 x) {
x.print("x argument inside f()");
out << "Returning from f()" << endl;
return x;
}
int main() {
HowMany2 h("h");
out << "Entering f()" << endl;
HowMany2 h2 = f(h);
h2.print("h2 after call to f()");
out << "Call f(), no return value" << endl;
f(h);
out << "After call to f()" << endl;
} ///:~
4、指向成员的指针
//: C11:PmemFunDefinition.cpp
class Simple2 {
public:
int f(float) const { return 1; }
};
int (Simple2::*fp)(float) const;
int (Simple2::*fp2)(float) const = &Simple2::f;
int main() {
fp = &Simple2::f;
} ///:~
+++++++++++++++++
//: C11:PointerToMemberFunction2.cpp
#include <iostream>
using namespace std;
class Widget {
void f(int) const { cout << "Widget::f()\n"; }
void g(int) const { cout << "Widget::g()\n"; }
void h(int) const { cout << "Widget::h()\n"; }
void i(int) const { cout << "Widget::i()\n"; }
enum { cnt = 4 };
void (Widget::*fptr[cnt])(int) const;
public:
Widget() {
fptr[0] = &Widget::f; // Full spec required
fptr[1] = &Widget::g;
fptr[2] = &Widget::h;
fptr[3] = &Widget::i;
}
void select(int i, int j) {
if(i < 0 || i >= cnt) return;
(this->*fptr[i])(j);
}
int count() { return cnt; }
};
int main() {
Widget w;
for(int i = 0; i < w.count(); i++)
w.select(i, 47);
} ///:~
参考
1、http://blog.163.com/chenglian_999@126/blog/static/76000279201021795656930
2、Thinking in C++