C++编码练习后知识小结

头一次记录技术相关知识,相信将来一定能看到自己的进步!

最近忙着找工作,因为要应对各种笔试。所以做了几个练习,不练不知道一练吓一跳。

发现自己对C++的基础知识几乎忘光了。突然感慨自己复制粘贴好多年的结果。。。

1.关于构造和析构顺序:

include "stdafx.h"

#include <iostream>

using namespace std;

class One

{

public:

            One(){cout<<"One ";}

            ~One(){cout<<"~One ";}

};

class Two

{

public:

             Two(int j){cout<<" Two ";}

            ~ Two(){cout<<"~ Two ";}

};

class Three

{

public:

            Three(){cout<<"Three ";}

            virtual ~Three(){cout<<"~Three ";}

};

class Four : public Three

{

public:

            Four (int j)

            {

                   cout<<"Four  ";

                   pb = new Two(j);

            }

            ~Four ()

            {

                   delete pb;

                   cout<<"~Four ";

            }

private:

            Two *pb;

            One a;

};

int _tmain(int argc, _TCHAR* argv[])

{

            Three* pc = new Four(1);

            delete pc;

            return 0;

}

Three One Four Two ~Two ~Four ~One ~Three

这个例子主要是说基类虚析构函数的作用。

从答案可以看出来,构造的顺序是基类,子类的成员对象,子类。

如果没有 pb = new Two(j)这句,只有Two *pb;则根本不会调用Two 的构造函数(突然觉得自己很傻,这根本就是显然是的事却犹豫了一下。。。)

如果class Three没有声明虚析构函数的话,则调用Delete pc语句的时候,不会调用其他的析构函数。

同样如果_tmain函数中的语句改为 Four* pc = new Four(1)

此时class three中是否为虚析构函数就无所谓了,delete时会按顺序调用其他类的析构函数。

总结一下,基类中的虚析构函数主要是用于防范上转型对象上(自己这么觉得)。

delete上转型对象时,如果此时基类的析构函数是虚函数,则顺序调用子类对象关联的其他类的析构函数。

如果此时基类的析构函数不是虚函数,则只调用基类的析构函数,这就为内存泄漏留下了隐患。

2.  关于Sizeof:

#include <iostream>

class A

{

public:

     A(){}

     A(int a,unsigned int b):m_a(a),m_b(b),m_c(){}

public:

     int m_a;

     unsigned int m_b;

     A* m_c;

};

class B : public A

{

public:

       B(){}

public:

       static int m_d;

};

int _tmain(int argc, _TCHAR* argv[])

{

       A* a;

       B b;

       std::cout<<sizeof(A)<<" ";

       std::cout<<sizeof(b)<<" ";

       std::cout<<sizeof(a)<<" ";

       a = new B[2];

       std::cout<<sizeof(a)<<" ";

       return 0;

}

答案是12 12 4 4    

一直以为unsigned int 的大小是2,今天试了一下原来是4。

再者因为a是指针所以a指向的所有东西sizeof都是4。不要被a = new B[2]所迷惑。

那天也遇到一个类似的问题,如果单纯的一个空类什么变量也没有,这个空类的sizeof是1(具体为什么是1还没搞清楚。~~老中医的Style,拿来就用嘛)

再者如果类中有静态参数,静态参数是不占空间的,估计是因为静态参数的存储不再类内的原因。初始化也不再类内。

3. 还是构造函数

#include <iostream>

class A

{

public:

A(int n=0):m_i(n){std::cout<<m_i;}

protected:

     int m_i;

};

class B : public A

{

public:

       B(int n):m_j(n),m_a(--m_j),m_b(){std::cout<<m_j;}

private:

     int m_j;

       A m_a;

       A m_b;

       static A m_c; 

};

int _tmain(int argc, _TCHAR* argv[])

{

     B b(2);

     std::cout<<std::endl;

     return 0;

}

 答案是0101        

这道题很诡异也是很好的一道题,一开始觉得答案肯定错了,一运行答案真的没错。。。

这道题主要是考察类的构造顺序和成员变量的初始化顺序。

第一个输出0是因为首先调用基类的构造函数,基类中默认参数是0。

第二个输出1是因为执行A m_a;时调用了A的构造函数,

由B的初始化列表B(int n):m_j(n),m_a(--m_j)可以看出首先对m_j赋值为2,

接着m_a(--m_j)将1传给A的构造函数所以输出1.

第三个输出0是因为A m_b;调用a的构造函数时没有传入参数,所以使用默认参数0.

第四个输出1是因为最后要调用B的构造函数,虽然传入的是2,但是之前的--m_j使m_j的值变成了1。

时间: 2024-08-25 15:19:33

C++编码练习后知识小结的相关文章

awk基础知识小结(2)

10.循环结构循环结构awk 的 while 循环结构,它等同于相应的 C 语言 while 循环.awk 还有 "do...while" 循环,它在代码块结尾处对条件求值,而不象标准 while 循环那样在开始处求值.它类似于其它语言中的 "repeat...until" 循环.示例:do...while 示例 {     count=1     do {    print "I get printed at least once no matter w

Android app开发知识小结

Android知识小结 这是一个知识的总结,所以没有详解的讲解. 一.分辨率Android中dp长度.sp字体使用.px像素.in英寸.pt英寸1/72.mm毫米 了解dp首先要知道density,density是一个抽象的单位,density值表示每英寸有多少个显示点,与分辨率是两个概念QVGA屏density=120         QVGA(240*320)HVGA屏density=160         HVGA(320*480)WVGA屏density=240        WVGA(

关闭selinux知识小结

今天有人问我,哎,福星,关闭selinux这块我还有点蒙,能给我分析分析么? selinux是什么? 1.     我的简单理解:selinux是一套安全的机制,在学习环境下建议关闭,功能方面可以一些机制所替代.比如防火墙等系列安全措施 selinux一定要关闭么? 1.     没有基础又不愿意倘坑的小伙伴可以关闭,工作中环境大都不开启 2.     开启的坏处是使用中需要倘很多的坑,如果有面对困难的勇气,那就别管它 修改selinux运行状态的相关 setenforce  1 | 0    

15天学习MVC后的小结(分享经历与想法)

学习MVC已经有半个月,看了看日历,刚好半个月.分享了好几篇练习的博文:一,<创建第一个MVC应用程序> http://www.cnblogs.com/insus/p/3358560.html二,<@Styles的nameSpace是什么>http://www.cnblogs.com/insus/p/3358703.html三,<MVC应用程序使用Entity Framework>http://www.cnblogs.com/insus/p/3359111.html四,

180531-Spring中JavaConfig知识小结

原文链接:Spring中JavaConfig知识小结/ Sring中JavaConfig使用姿势 去掉xml的配置方式,改成用Java来配置,最常见的就是将xml中的 bean定义, scanner包扫描,属性文件的配置信息读取等 I. 几个基本注解 1. Configuration注解 在javaConfig中注解@Configuration用来代替一个xml文件,可以简单的理解他们的作用是相等的,一般bean的定义也都是放在被这个注解修饰的类中 如一个基本的配置文件如下 @Configura

awk基础知识小结(1)

1.使用规则 awk 适合于文本处理和报表生成,它还有许多精心设计的特性,允许进行需要特殊技巧程序设计. awk  的语法较为常见.它借鉴了某些语言的一些精华部分,如C 语言.python 和 bash. 第一个 awk 让我们继续,开始使用 awk,以了解其工作原理.在命令行中输入以下命令: $ awk '{ print }'  /etc/passwd 您将会见到 /etc/passwd 文件的内容出现在眼前.现在,解释 awk 做了些什么.调用 awk 时,我们指定  /etc/passwd

C/C++ 位域知识小结

C/C++ 位域知识小结 几篇较全面的位域相关的文章: http://www.uplook.cn/blog/9/93362/ C/C++位域(Bit-fields)之我见 C中的位域与大小端问题 内存对齐全攻略–涉及位域的内存对齐原则 本文主要对位域相关知识进行了一下梳理,参考如下: C语言中的位域 史上最全的C位域总结2 C结构体之位域(位段) C/C++中以一定区域内的位(bit)为单位来表示的数据成为位域,位域必须指明具体的数目. 位域的作用主要是节省内存资源,使数据结构更紧凑. 1. 一

suid知识小结

1.1.1 suid知识小结:针对命令和二进制程序 1)用户或属主对应的前三位权限的x位上如果有s就表示suid权限.当x位上没有小写x执行权限的时候,suid的权限显示的就是大S. 2)suid作用是让普通用户可以以root(或其他)的用户角色运行只有root(或其他)账号才能运行的程序或命令,或程序命令对应本来没有权限操作的文件等.(注意和su及sudo的区别),suid为某个命令设置特殊权限(使用者为所有人).通过给rm命令设置suid加深学生对suid的理解. 3)问题:希望oldboy

javascript之正则表达式基础知识小结

javascript之正则表达式基础知识小结,对于学习正则表达式的朋友是个不错的基础入门资料. 元字符 ^ $ . * + ? = ! : | \ / ( ) [ ] { } 在使用这些符号时需要用“\”来进行转移. 如果记不清楚那些标点符号需要转移,可以在使用标点符号时都使用反斜杠“\” 简单匹配 1.直接量 /javascript/ 匹配带有“javascript”的字符串 比如“javascript is an object-oriented scripting language” 2.[