c++语言中引起二义性的问题之 构造函数不可小觑!
2013-06-03 19:08
393 查看
本次讲述 在c++语言中引起二义性的问题之 构造函数不可小觑!
引发的实质是 函数的重载和默认参数值 所以一般的重载函数函数 也会出现这样的问题,今天以构造函数为例介绍的目的是捎带讲解一些构造函数的问
题!
#include <iostream>
using namespace std;
class a
{
int n,j;// 注:当类中的成员没有设置访问权限的话,就会默认为: 私有的 ,这和 struct 有所不同 他会默认为:公有的类型!
public:
a() //类的无参构造函数
{}//需要说明一下 就算是函数体为空的函数 也要有{}花括号否则就会报错的!但是好像 类的纯虚函数例外吧!
a(int b,int m)//这里是类的有参构造函数
{
b=n;
j=m;
}
};
int main()
{
a m(4,4);
system("pause");
return 0;
}
上面的这个程序 中有一个 无参构造函数 有一个类的有参构造函数,当在主函数里声明和定义类a 的对象的时候,要通过类的构造函数来给成员数据
初始化使用,但是类的构造函数的调用是隐式地在定义类的对象的时候自动的调用的,如果类中一个也没用声明和定义类的构造函数的话,就调用
类的默认构造函数 即缺省构造函数(无参构造函数),但是他什么也不做!此时 【类名 对象名】 这样定义对象!此时若用函数将类的成员数据
输出的话,将会输出一个任意的数值,因为你没有成功的将其初始化!
对于上面的程序来说引发错误 的原因在于 定义的时候:请看 a m 后面没有()就调用类的无参构造函数 (即对于调用无参构造函数来说,后面是不用加括号的,但是对于一般的函数来说是不行的!),a m(4, 5)此时就调用类的有参构造函数
但是 a m(4)时 编译器不能根据 对象后面的类型来选择调用对应的构造函数,(即 这个程序 构造函数也运用到了函数的重载机制!)。
看下面的程序代码:
#include <iostream>
using namespace std;
class a
{
int n,j;
public:
a()
{}
a(int b=1,int m=8) 这里是类的有全部默认参数值的构造函数
{
b=n;
j=m;
}
};
int main()
{
a m; 看这里 用类a 定义了一个 对象 m
system("pause");
return 0;
}
这个程序你如果在a 的对象定义时将会出现许多的二义性问题(还有其他的小问题):
1: a m;
出错 因为本程序中存在一个类的有全部默认参数值的构造函数 当存在全部都是默认参数值的构造函数时调用全部都是默认参数值的构造函数时,类的对
象后面也不用加()但是赋的值是默认的参数值,也可以加()括号进行赋值从左到右依次赋值,没有的话就使用默认的参数值。
但是问题出现了: 对于 a m 这个语句来说 编译器分辨不出来到底调用哪个构造函数!,所以二义性就出现了!
解决的办法: 要么将 类的无参构造函数 要么不要使用这样的定义方式 a m 即可以这样 a(4),a(4,5);但是这样的话赋的值就是定义对象时提供参数,依次 从左向右赋值的。在此讲述一下函数的带有默认参数值问题:正如前面讲到的 函数的赋值是是依次 从左向右赋值的,所以说,如果一个函数的
形参被指定为默认值的话,那么位于他右侧的所有形参都必须指定默认值,也就是说在一个制定了的默认值的形参的后面跟随没有形参值的形参是不合法
的!原因不再多余解释!
回到这个程序来说 也就是说在这个情况下类的无参构造函数 是不能用了!
看下面这个程序:
#include <iostream>
using namespace std;
class a
{
int n,j;
public:
a()
{}
a(int v)
a(int b,int m=8) 这里是类的有全部默认参数值的构造函数
{
b=n;
j=m;
}
};
int main()
{
a m(4); 看这里 用类a 定义了一个 对象 m
system("pause");
return 0;
}
从上面的程序中看来无参数的构造函数是不会引起二义性了但是 其它的构造函数 改了 当这样 a m(4)时,第二个和第三个构造函数就会发生二义性的
的问题,怎么解决,要么这样定义a m(4 ,5) ,或者 a m不加括号,要么将第三个构造函数全部都定义为 有默认参数但是此时就只能 a m(4 ,5)调用
了,其它都会引发二义性的,要么将第三个构造函数全部都定义为 没有默认参数的此时就可以根据参数的数值,编译器就可以选择性的调用了!
对于这样类型的问题还有各式各样形式!
总之 这个引发二义性的问题 是由函数的重载加上默认参数值 共同引发的经过上面的讲述,请大家灵活的掌握!
另外:要说明的是当类中只要声明定义了一个构造函数那么以后类的默认构造函数即缺省构造函数就不再起作用,即使你的构造函数
是类的无参构造函数 !
引发的实质是 函数的重载和默认参数值 所以一般的重载函数函数 也会出现这样的问题,今天以构造函数为例介绍的目的是捎带讲解一些构造函数的问
题!
#include <iostream>
using namespace std;
class a
{
int n,j;// 注:当类中的成员没有设置访问权限的话,就会默认为: 私有的 ,这和 struct 有所不同 他会默认为:公有的类型!
public:
a() //类的无参构造函数
{}//需要说明一下 就算是函数体为空的函数 也要有{}花括号否则就会报错的!但是好像 类的纯虚函数例外吧!
a(int b,int m)//这里是类的有参构造函数
{
b=n;
j=m;
}
};
int main()
{
a m(4,4);
system("pause");
return 0;
}
上面的这个程序 中有一个 无参构造函数 有一个类的有参构造函数,当在主函数里声明和定义类a 的对象的时候,要通过类的构造函数来给成员数据
初始化使用,但是类的构造函数的调用是隐式地在定义类的对象的时候自动的调用的,如果类中一个也没用声明和定义类的构造函数的话,就调用
类的默认构造函数 即缺省构造函数(无参构造函数),但是他什么也不做!此时 【类名 对象名】 这样定义对象!此时若用函数将类的成员数据
输出的话,将会输出一个任意的数值,因为你没有成功的将其初始化!
对于上面的程序来说引发错误 的原因在于 定义的时候:请看 a m 后面没有()就调用类的无参构造函数 (即对于调用无参构造函数来说,后面是不用加括号的,但是对于一般的函数来说是不行的!),a m(4, 5)此时就调用类的有参构造函数
但是 a m(4)时 编译器不能根据 对象后面的类型来选择调用对应的构造函数,(即 这个程序 构造函数也运用到了函数的重载机制!)。
看下面的程序代码:
#include <iostream>
using namespace std;
class a
{
int n,j;
public:
a()
{}
a(int b=1,int m=8) 这里是类的有全部默认参数值的构造函数
{
b=n;
j=m;
}
};
int main()
{
a m; 看这里 用类a 定义了一个 对象 m
system("pause");
return 0;
}
这个程序你如果在a 的对象定义时将会出现许多的二义性问题(还有其他的小问题):
1: a m;
出错 因为本程序中存在一个类的有全部默认参数值的构造函数 当存在全部都是默认参数值的构造函数时调用全部都是默认参数值的构造函数时,类的对
象后面也不用加()但是赋的值是默认的参数值,也可以加()括号进行赋值从左到右依次赋值,没有的话就使用默认的参数值。
但是问题出现了: 对于 a m 这个语句来说 编译器分辨不出来到底调用哪个构造函数!,所以二义性就出现了!
解决的办法: 要么将 类的无参构造函数 要么不要使用这样的定义方式 a m 即可以这样 a(4),a(4,5);但是这样的话赋的值就是定义对象时提供参数,依次 从左向右赋值的。在此讲述一下函数的带有默认参数值问题:正如前面讲到的 函数的赋值是是依次 从左向右赋值的,所以说,如果一个函数的
形参被指定为默认值的话,那么位于他右侧的所有形参都必须指定默认值,也就是说在一个制定了的默认值的形参的后面跟随没有形参值的形参是不合法
的!原因不再多余解释!
回到这个程序来说 也就是说在这个情况下类的无参构造函数 是不能用了!
看下面这个程序:
#include <iostream>
using namespace std;
class a
{
int n,j;
public:
a()
{}
a(int v)
a(int b,int m=8) 这里是类的有全部默认参数值的构造函数
{
b=n;
j=m;
}
};
int main()
{
a m(4); 看这里 用类a 定义了一个 对象 m
system("pause");
return 0;
}
从上面的程序中看来无参数的构造函数是不会引起二义性了但是 其它的构造函数 改了 当这样 a m(4)时,第二个和第三个构造函数就会发生二义性的
的问题,怎么解决,要么这样定义a m(4 ,5) ,或者 a m不加括号,要么将第三个构造函数全部都定义为 有默认参数但是此时就只能 a m(4 ,5)调用
了,其它都会引发二义性的,要么将第三个构造函数全部都定义为 没有默认参数的此时就可以根据参数的数值,编译器就可以选择性的调用了!
对于这样类型的问题还有各式各样形式!
总之 这个引发二义性的问题 是由函数的重载加上默认参数值 共同引发的经过上面的讲述,请大家灵活的掌握!
另外:要说明的是当类中只要声明定义了一个构造函数那么以后类的默认构造函数即缺省构造函数就不再起作用,即使你的构造函数
是类的无参构造函数 !
相关文章推荐
- c++语言中易引起二义性问题 2 之类的继承问题以及成员数据覆盖问题不如忽视!
- C/C++日常学习总结(第六篇)多基派生引起的虚函数访问二义性问题&重载,覆盖,隐藏的区别
- 事务和线程的区别还有事务并发执行引起的四个问题:丢失修改、脏读、不可重复读,幻读
- pt-online-schema-change使用中的不当,引起的数据库不可写入问题
- 派生类构造函数和多重继承的二义性问题
- EF(Entity Framework)发生错误”正在创建模型,此时不可使用上下文“的解决办法。 正在创建模型,此时不可使用上下文。如果在 OnModelCreating 方法内使用上下文或如果多个线程同时访问同一上下文实例,可能引发此异常。请注意不保证 DbContext 的实例成员和相关类是线程安全的。 临时解决了这个问题,在Context的构造函数中,禁用了自动初始化:
- 多重继承引起的二义性问题
- C++为什么可以进行函数重载以及引起的二义性问题
- 在DOc的构造函数中得到VIew类指针引起的问题(GetActiveView()引起的Access Violation;this->GetFirstViewPosition()=NULL;ASSERT(AfxIsValidAddress(this, siz
- IPv4 向 IPv6 过渡安全问题不可小觑
- 今天犯了一个StringBuilder构造函数引起的二逼问题。
- mvc路由引起异步调用web服务的问题
- DOCTYPE引起的一系列问题-->Select样式,文本框样式width100%超过父容器
- 大话C++----默认参数及其所引起的二义性
- 域名访问和ip访问引起的http 403问题
- 代码不规范在weblogic中引起jsp页面404问题
- 解决:浏览页面时,出现"WebDev.WebServer.exe 遇到问题需要关闭。我们对此引起的不便表示抱歉。"问题
- c++有关构造函数和析构函数中调用虚函数问题
- 【问题汇总】透明Activity引起的问题
- C++ 二义性问题