这本书虽然叫这个名字,但是好像与设计模式没有什么关系,介绍的大部分是C++基础和Qt基础,不过无所谓了,查漏补缺,把忘记过的一些知识点再记录一下。
1.编译器确定应该调用哪一个重载函数的步骤:
(1)如果存在一个完全匹配的函数,则调用此函数。
(2)否则,通过标准的类型提升转换来进行匹配。
(3)否则,通过转换构造函数或者转换运算符来进行匹配。
(4)否则,判断是否可以通过省略号(...)来进行匹配。
(5)否则,编译器报错。
看下例子:
class SignDemo{
public:
SignDemo(int val):m_val(val){}
void demo(int n)
{
cout<<++m_val<<"\tdemo(int)"<<endl;
}
void demo(int n) const
{
cout<<m_val<<"\tdemo(int) const"<<endl;
}
// void demo(const int &n) //与上面的函数重复
// {
// cout<<++m_val<<"\tdemo(const int &)"<
// }
void demo(short n)
{
cout<<++m_val<<"\tdemo(short)"<<endl;
}
void demo(float n)
{
cout<<++m_val<<"\tdemo(float)"<<endl;
}
void demo(float n) const
{
cout<<m_val<<"\tdemo(float) const"<<endl;
}
void demo(double n)
{
cout<<++m_val<<"\tdemo(double)"<<endl;
}
private:
int m_val;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
SignDemo sd(5);
const SignDemo csd(17);
sd.demo(2); //6 demo(int) 当没有注释掉上面的那个函数时 ,error
csd.demo(2);//17 demo(int) const
int i = 3;
sd.demo(i);//7 demo(int)
short s = 5;
sd.demo(s);//8 demo(short)
csd.demo(s);//17 demo(int) const 不能调用非const 的short函数 所以提升调用int 的const
sd.demo(2.3);//9 demo(double)注意为double
float f(4.5);
sd.demo(f);//10 demo(float)
csd.demo(f);//17 demo(float) const
//csd.demo(4.5);//调用int const 还是 float const 傻傻分不清楚
return a.exec();
}
一、
class Person{
public:
void setName(QString name)//修改临时变量的值
{
name += "wgy";
m_strName = name;
}
QString getName()
{
return m_strName;
}
QString& getNameV() //从函数返回临时变量的引用,编译器会发生警告, 有的编译器运行会出错
{
QString str = m_strName;
return str;
}
private:
QString m_strName;
};
二、内联函数
inline int max(int a,int b)
{
return a>b? a:b;
}
int main(int argc, char *argv[])
{
int temp = max(3,5);
etc...
//编译器会将max的代码展开如下
int temp;
{
int a = 3;
int b = 5;
temp = a>b? a:b;
}
etc...
}
如果要重复地调用(例如,在一个大型循环中),则inline函数可极大地提高性能。inline函数的缺点时会使编译代码变得更大, 在运行时会占用更多内存。对于需要调用许多次的小型函数,将其声明成inline对内存的影响使微小的,而潜在的性能提升收益会很大。
inline函数与#define宏类似,但有一个重大差异:对#define宏的替换过程是由预处理器处理的,预处理器本质上就是一个文本编辑器。对inline函数的替换过程是由编译器处理的,它会执行更智能的操作,进行正确的类型检查。
https://www.cnblogs.com/fnlingnzb-learner/p/6423917.html
三、带变长实参的函数。
double mean(int n ...)
{
va_list ap;//ap指向每一个为命名的实参
double sum(0);
int count(n);//实参的个数
va_start(ap,n);//ap从第一个为命名的实参开始
for (int i=0;i<count;i++)
{
sum += va_arg(ap,double);
}
va_end(ap);//返会之前清除栈
return sum/count;
}
int main(int argc, char *argv[])
{
cout<<mean(4,11.3,45.1,15.6,12.9)<<endl;
}
Qt中很多数据类型(QVariant支持的,例如:QList,QImage,QString,QMap,QHash等)都是隐式共享,写时复制,引用计数等。下面拿QString举个例子:
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString s1 = "dsdw";
QString s2 = s1;
//s1.clear();
qDebug()<<s1<<s2;
s2 = "dsdada";
qDebug()<<s1<<s2;
return a.exec();
}
当s1赋值给s2时,二者的地址是一样的。指向同一块内存,输出一样。(隐式共享)
当我们clear s1时,s1的地址发生了变化,但是s2还是指向那块内存,这时只是引用计数 -1,如果是浅拷贝,那么s2也会被清空,如果是深拷贝,那么s1赋值s2的时候,就不会地址一样。
但是当我们重新给s2赋值时,这时的s2的地址发生了变换(copy on write)
QObject没有公有的复制构造函数或赋值构造函数。向下到QObject类定义的结尾有一个宏Q_DISABLE_COPY(QObject),它显示的确保QObject不会被复制。
父对象存储子对象们的地址,一般按照添加顺序,但是某些情况下会该变顺序,例如:将一个窗口从后面提升到前面。
每个父对象知道它的子对象的地址,子对象知道它的父对象的地址。
w->setParent(W);w->setParent(Z); w会从W的列表中被删除,同时w的父对象也会改变。这叫重父化
https://www.cnblogs.com/suzhou/p/dp16obsvr.html
与观察者模式的实现对应下,恍然大悟。
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
return a.exec();
}
今天先写到这。。。。