c语言,c++,哪些运算符不能重载?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言,c++,哪些运算符不能重载?相关的知识,希望对你有一定的参考价值。

c语言没有重载的概念,重载是C++的内容
c++运算符:
算术运算符:+,-,*,/,%,++,--;
位操作运算符:&,|,~,^(位异或),<<(左移),>>(右移)
逻辑运算符:!,&&,||;
比较运算符:<,>,>=,<=,==,!=;
赋值运算符:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=;
其他运算符:[],(),->,,(逗号运算符),new,delete,new[],delete[],->*。

不能重载的总共五个:
(1) "."(类成员访问运算符)
(2)" .*"(类成员指针访问运算符)
(3) "::"(域运算符)
(4)"siezof"(长度运算符)
(5) " ?:"(条件运算符)
还有就是:typeid.
其中
.*是C++的类成员函数指针调用运算符,是用来调用一个类函数指针的。
举例:
假设有一个ClassA类拥有一个成员函数void ClassA::func(int i),则可以这么用:

1
2
3
4

void (ClassA::*fp)(int i) // 定义一个类函数指针。
ClassA obj;
fp = &ClassA::func; // 给这个类函数指针赋值
(obj.*fp)(5); // 这么用,相当于调用obj.func(5);

没有什么非禁止operator?:重载的理由,只不过没有必要而已。另外,expr1?expr2:expr3的重载函数无法保证expr2和expr3中只有一个被执行。
而“sizeof”无法被重载是因为不少内部操作,比如指针加法,都依赖于它,例如:

X a[10];
X* p = &a[3];
X* q = &a[3];
p++; // p points to a[4]
// thus the integer value of p must be
// sizeof(X) larger than the integer value of q

这样,sizeof(X)无法在不违背基本语言规则的前提下表达什么新的语义。
在N::m中,N和m都不是表达式,它们只是编译器“认识”的名字,“::”执行的实际操作是编译时的名字域解析,并没有表达式的运算牵涉在内。或许有人会觉得重载一个“x::y”(其中x是实际对象,而非名字域或类名)是一个好主意,但这样做引入了新的语法[译注:重载的本意是让操作符可以有新的语义,而不是更改语法——否则会引起混乱],我可不认为新语法带来的复杂性会给我们什么好处。

原则上来说,“.”运算符是可以被重载的,就像“->”一样。不过,这会带来语义的混淆——我们到底是想和“.”后面的对象打交道呢,还是“.”后面的东东所实际指向的实体打交道呢?看看这个例子(它假设“.”重载是可以的):

class Y
public:
void f();
// ...
;

class X // assume that you can overload . public:
Y* p;
Y& operator.() return *p;
void f();
// ...
;

void g(X& x)

x.f(); // X::f or Y::f or error?


请注意:
1. 重载不能改变该运算符用于内置类型时的函义,程序员不能改变运算符+用于两个int型时的含义。

2. 运算符函数的参数至少有一个必须是类的对象或者类的对象的引用。这种规定可以防止程序员运用运算符改变内置类型的函义。
3. 重载不能改变运算符的优先级。
4. 重载不能改变运算符的结合律。
5. 重载不能改变运算符操作数的个数。比如+需要两个操作数,则重载的+也必须要有两个操作数。
参考技术A

c++运算符:

 算术运算符:+,-,*,/,%,++,--;
位操作运算符:&,|,~,^(位异或),<<(左移),>>(右移)
逻辑运算符:!,&&,||;
比较运算符:<,>,>=,<=,==,!=;
赋值运算符:=,+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=;
其他运算符:[],(),->,,(逗号运算符),new,delete,new[],delete[],->*。 


不能重载的总共五个:

(1) "."(类成员访问运算符) 

(2)" .*"(类成员指针访问运算符) 

(3) "::"(域运算符) 

(4)"siezof"(长度运算符) 

(5) " ?:"(条件运算符)

还有就是:typeid.

其中

 .*是C++的类成员函数指针调用运算符,是用来调用一个类函数指针的。
举例:
假设有一个ClassA类拥有一个成员函数void ClassA::func(int i),则可以这么用:

void (ClassA::*fp)(int i) // 定义一个类函数指针。
ClassA obj; 
fp = &ClassA::func; // 给这个类函数指针赋值
(obj.*fp)(5); // 这么用,相当于调用obj.func(5);


没有什么非禁止operator?:重载的理由,只不过没有必要而已。另外,expr1?expr2:expr3的重载函数无法保证expr2和expr3中只有一个被执行。
而“sizeof”无法被重载是因为不少内部操作,比如指针加法,都依赖于它,例如:

X a[10];
X* p = &a[3];
X* q = &a[3];
p++; // p points to a[4]
// thus the integer value of p must be
// sizeof(X) larger than the integer value of q

这样,sizeof(X)无法在不违背基本语言规则的前提下表达什么新的语义。
在N::m中,N和m都不是表达式,它们只是编译器“认识”的名字,“::”执行的实际操作是编译时的名字域解析,并没有表达式的运算牵涉在内。或许有人会觉得重载一个“x::y”(其中x是实际对象,而非名字域或类名)是一个好主意,但这样做引入了新的语法[译注:重载的本意是让操作符可以有新的语义,而不是更改语法——否则会引起混乱],我可不认为新语法带来的复杂性会给我们什么好处。

原则上来说,“.”运算符是可以被重载的,就像“->”一样。不过,这会带来语义的混淆——我们到底是想和“.”后面的对象打交道呢,还是“.”后面的东东所实际指向的实体打交道呢?看看这个例子(它假设“.”重载是可以的):

class Y 
public:
void f();
// ...
;

class X  // assume that you can overload . public:
Y* p;
Y& operator.()  return *p; 
void f();
// ...
;

void g(X& x)

x.f(); // X::f or Y::f or error?


请注意:

1. 重载不能改变该运算符用于内置类型时的函义,程序员不能改变运算符+用于两个int型时的含义。

2. 运算符函数的参数至少有一个必须是类的对象或者类的对象的引用。这种规定可以防止程序员运用运算符改变内置类型的函义。

3. 重载不能改变运算符的优先级。
4. 重载不能改变运算符的结合律。
5. 重载不能改变运算符操作数的个数。比如+需要两个操作数,则重载的+也必须要有两个操作数。

本回答被提问者采纳

以上是关于c语言,c++,哪些运算符不能重载?的主要内容,如果未能解决你的问题,请参考以下文章

C++运算符重载时要遵循的规则

c++重载赋值操作符的返回值是啥?

C++入门不能重载为友元函数的4个运算符(=, ->, [ ], ( ))

C++学习(四七一)重载运算符

[C++潜心修炼] operator重载

运算符重载的宏观思考The Complex Class