网站流量查询 优帮云,网页在线设计软件,企业网站图片渐变效果怎么做,促销方案本期的主要内容是箭头运算符以及它对于结构体与类的指针可以做什么#xff0c;最后实现我们自己的运算符重载。
01 为什么要使用运算符重载
从开发的角度而言#xff0c;运算符重载的存在是为了提高开发效率#xff0c;增加代码的可复用性#xff0c;很多时候简化了代码。…本期的主要内容是箭头运算符以及它对于结构体与类的指针可以做什么最后实现我们自己的运算符重载。
01 为什么要使用运算符重载
从开发的角度而言运算符重载的存在是为了提高开发效率增加代码的可复用性很多时候简化了代码。
C强大的原因之一是支持泛型编程。泛型编程使得算法可以独立于数据类型存在。自定义的数据类型通过操作符重载具有了和内建类型同样的使用接口然后C的模板加持下你的算法可以利用这种接口一致性实现泛化。 1.1 如何使用运算符重载
这是一个基本的 Entity 类有一个输出提示语的 Print 函数。
#include iostream
#include stringclass Entity
{
public:void Print() const { std::cout Hello! std::endl; }
};int main()
{std::cin.get();
}如果按照正常的使用方法我们会这样创建对象。
int main()
{Entity e;e.Print();std::cin.get();
}可如果是在堆上创建的或者出于某种原因程序中有一个指向它的指针为了调用 Print 函数该怎么办呢这个时候就不能使用 . 了下面的写法很明显是错的。
int main()
{Entity e;e.Print();Entity* ptr e;ptr.Print();std::cin.get();
}因为 ptr 只是一个指针也就是一个数值不是对象无法调用方法。
我们可以使用逆向引用 ptr 来实现调用 Print 函数使用括号是因为符号的优先级的原因。
int main()
{Entity e;e.Print();Entity* ptr e;(*ptr).Print();std::cin.get();这样写当然没有问题但它看起里有点笨重。
我们可以使用箭头运算符来简化这个操作。
int main()
{Entity e;e.Print();Entity* ptr e;ptr-Print();std::cin.get();
}这样的操作就相当于逆向引用了 Entity 指针。
这就是它的全部内容了。
它只是一个快捷方式成员变量也是同样的道理。
箭头运算符作为一个操作符我们实际上可以重载它并在你自定义类中使用它。
我们一起来看一个例子来说明为什么要这么做以及怎么做。
假设我正在写一个智能指针的类如下所示。
class ScopePtr
{
private:Entity* m_Obj;
public:ScopePtr(Entity* entity):m_Obj(entity){}~ScopePtr(){delete m_Obj;}
};这是一个基本的 ScopePtr 类当 Entity 超出范围时这个类会自动删除它。
我可以这样使用它。
int main()
{ScopePtr entity new Entity();std::cin.get();
}我希望能够调用 Print 函数该怎么做呢
首先我不能用 . 符号但我可以将 m_Obj 变成 public 的或者写一个 GetObject 函数返回一个 Entity 指针类似下面这样写法。
int main()
{ScopePtr entity new Entity();entity.GetObject()-Print();std::cin.get();
}不过这方法看起来太乱了我希望能够使用堆分配的 Entity 一样使用它类似于下面这样用法。
int main()
{ScopePtr* entity new Entity();entity-Print();std::cin.get();
}这就是我们想要重载箭头运算符的原因。
重载箭头运算符。
总结
良好的重载除了提高写代码的效率也往往降低了代码维护的成本更容易减少bug提高代码质量增加可读性。
如果非要说带来了什么负面影响我觉得往往还是人为的原因。没有做好抽象导致滥用运算符重载。如果设计不好接口的话还是不要强行引入运算符重载这样可能反而降低代码可读性增加耦合。