补充重载运算符

补充重载运算符

重载运算符

http://blog.163.com/zhoumhan_0351/blog/static/399542272010027113311390

1、只有那些包含用户自定义类型的表达式才能有重载的运算符。

return int(2+3); 

返回临时对象。临时对象必然是常对象,且不会执行析构函数,只需要一个普通的构造函数调用。效率高,称为返回值优化。

operator->:指针间接引用运算符一定是一个成员函数,必须返回对象或引用,或指针。

operator->*:必须返回对象。对于这个对象,可以用正在调用的成员函数为参数调用operator()。operator()调用必须是成员函数,它是惟一允许在它里面有任意个参数的函数。

//: C12:PointerToMemberOperator.cpp

#include <iostream>

using namespace std;

class Dog {

public:

  int run(int i) const { 

cout << "run\n";  

return i; 

  }

  int eat(int i) const { 

 cout << "eat\n";  

 return i; 

  }

  int sleep(int i) const { 

cout << "ZZZ\n"; 

return i; 

  }

  typedef int (Dog::*PMF)(int) const;

  // operator->* must return an object 

  // that has an operator():

  class FunctionObject {

Dog* ptr;

PMF pmem;

  public:

// Save the object pointer and member pointer

FunctionObject(Dog* wp, PMF pmf) 

  : ptr(wp), pmem(pmf) { 

  cout << "FunctionObject constructor\n";

}

// Make the call using the object pointer

// and member pointer

int operator()(int i) const {

  cout << "FunctionObject::operator()\n";

  return (ptr->*pmem)(i); // Make the call

}

  };

  FunctionObject operator->*(PMF pmf) { 

cout << "operator->*" << endl;

return FunctionObject(this, pmf);

  }

};

int main() {

  Dog w;

  Dog::PMF pmf = &Dog::run;

  cout << (w->*pmf)(1) << endl;

  pmf = &Dog::sleep;

  cout << (w->*pmf)(2) << endl;

  pmf = &Dog::eat;

  cout << (w->*pmf)(3) << endl;

} ///:~

2、基本方针

3、构造函数的调用

#include "iostream"

using namespace std;

class Fi{

public:

 Fi() {}

};

class Fee{

private:

 int i;

public:

 Fee(int i) {cout<<"Fee(int)"<<endl;}

 Fee(const Fi&) {cout<<"Fee(const Fi Fi)"<<endl;}

};

int main()

{

Fee fee=1;

Fee fee2(1);//效果一样

Fi fi;

Fee fum=fi;

Fee fum2(fi);

return 1;

}

应当注意:给两个相同类型的对象赋值时,应当检查一下自赋值。

DogHouse& operator=(const DogHouse& dh) {

// Check for self-assignment:

if(&dh != this) {

  p = new Dog(dh.p, " assigned");

  houseName = dh.houseName + " assigned";

}

return *this;

  }

4、引用计数

如果对象需要大量的内存来运行拷贝构造函数。应当避免。一种方法是使用引用引数。使一块存储单元具有智能,它知道有多少对象指向它。拷贝构造函数或赋值运算意味着把另外的指针指向现在的存储单元并增加引用计数,反之。

此外,To solve this“aliasing”problem(多个指针指向同一块内存时的修改问题),引入写拷贝技术:在向这块存储单元写入前,应该确信没有他人在用,如果引用计数大于1,写之前应拷贝这块存储单元。

Dog* unalias() {

cout << "Unaliasing Dog: " << *this << endl;

// Don't duplicate if not aliased:

if(refcount == 1) return this;

--refcount;

// Use copy-constructor to duplicate:

return new Dog(*this);

  }

5、如果用户没有创建type::operator=(type),则编译器会自动创建一个。

#include <iostream>

using namespace std;

class Cargo {

public:

  Cargo& operator=(const Cargo&) {

cout << "inside Cargo::operator=()" << endl;

return *this;

  }

};

class Truck {

  Cargo b;

};

int main() {

  Truck a, b;

  a = b; // Prints: "inside Cargo::operator=()"

} ///:~

    为Truck自动生成的operator调用Cargo& operator=。

6、自动类型转换

关于类型转换函数和转换构造函数的讨论

http://blog.163.com/zhoumhan_0351/blog/static/39954227201002702424657

1)构造函数转换

    //: C12:AutomaticOperatorEquals.cpp

class One {

public:

  One() {}

};

class Two {

public:

  Two(const One&) {}

  explicit Two(const One&) {}

};

void f(Two) {}

int main() {

  One one;

  f(one); // Wants a Two, has a One

} ///:~

    有时这可能会问题,可在构造函数加explicit来阻止显式的自动转换。创建一个单一参数的构造函数总是定义一个自动类型转换(即使不止一个参数,其它参数将被默认处理)。

2)运算符转换

7、类型转换的例子

如果不用自动类型转换就想用从标准的C库函数中使用所有的字符串函数,就得为每个函数写一个相应的成员函数,如下所示:

int strcmp(const Stringc& S) const {

    return ::strcmp(s.c_str(), S.s.c_str());

  }

.........

如果用自动类型转换:

operator const char*() const { 

    return s.c_str(); 

  }

则编译器会知道如何将当前的string型转换成char*,所以任何一个接受char*的函数也可接收string参数。

    当然,有时自动类型转换可能会产生二义性,解决方法是只定义一种。

class Orange {};

class Pear {};

class Apple {

public:

  operator Orange() const;

  operator Pear() const;

};

// Overloaded eat():

void eat(Orange);

void eat(Pear);

int main() {

  Apple c;

//! eat(c);

  // Error: Apple -> Orange or Apple -> Pear ???

} ///:~

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值