精华内容
下载资源
问答
  • C++ Class Size (C++ 类大小)

    千次阅读 2014-07-24 09:55:35
    C++ Class Size (C++ 类大小)  2013-03-17 20:05:34| 分类: C++ | 标签:c++ class size 类大小  |举报 |字号 订阅 最近在写B+Tree的时候突然发现对类节点的大小没算准,导致不知道固定...

    C++ Class Size (C++ 类大小)  

    最近在写B+Tree的时候突然发现对类节点的大小没算准,导致不知道固定大小的内存可以存几个节点。Google上得到了不少资料,先加以整理并加入一些自己的测试;一下都是linux环境输出的记过,windows vc++输出结果会不一样的,原文出处:C++ Class Size,windows相关的是我自己添加上去的。

    涉及到c++中求类大小时需要特别注意一下几点

    1.为类的非静态成员数据的类型大小之和.

    2.有编译器额外加入的成员变量的大小,用来支持语言的某些特性(如:指向虚函数的指针、虚继承、多重继承).

    3.为了优化存取效率,进行的边缘调整.

    4.  与类中的构造函数,析构函数以及其他的成员函数无关.

     5.  私有继承,会去继承之前的私有成员变量么? 会...在内存中仍然分配相应的空间,只是在子类中是不可见的!

     6.  在做多层次的继承类大小时某个子类的类大小总是等于父类的大小加上子类中数据成员和是否有虚函数,是否是虚继承等因素来决定。

    • 空类大小为1
         首先:我们要知道什么是类的实例化,所谓类的实例化就是在内存中分配一块地址.

    那我们先看看一个例子:

    #include<iostream.h>

    class a {};
    class b{};
    class c:public a{
    virtual void fun()=0;
    };
    class d:public b,public c{};
    int main()
    {
    cout<<"sizeof(a)"<<sizeof(a)<<endl;
    cout<<"sizeof(b)"<<sizeof(b)<<endl;
    cout<<"sizeof(c)"<<sizeof(c)<<endl;
    cout<<"sizeof(d)"<<sizeof(d)<<endl;
    return 0;}

    程序执行的输出结果为:

    sizeof(a) =1

    sizeof(b)=1

    sizeof(c)=4

    sizeof(d)=8 

    上面是在VC++6.0编译的结果,但是在Dev-C++和Code::Blocks下得出的结果是 sizeof( d ) = 4

    为什么会出现这种结果呢?初学者肯定会很烦恼是吗?类a,b明明是空类,它的大小应该为为0,为什么 编译器输出的结果为1呢?这就是我们刚才所说的实例化的原因(空类同样可以被实例化),每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址.所以a,b的大小为1.

    • 虚函数

    [cpp] 
    #include<iostream> 
    using namespace std; 
    class A 

    public: 
        virtual void aa(){} 
    private: 
        char k[3]; 
    }; 
    class B: public A 

    public: 
        virtual void bb(){} 
    }; 
    int main() 

        cout<<"A's size is "<<sizeof(A)<<endl; 
        cout<<"B's size is "<<sizeof(B)<<endl; 
        return 0; 

    VS和gcc下执行结果:

    A's size is 8

    B's size is 8

    说明:有虚函数的类有个virtual table(虚函数表),里面包含了类的所有虚函数,类中有个virtual table pointers,通常成为vptr指向这个virtual table,占用4个字节的大小。成员类B public继承于A,类B的虚函数表里实际上有两个虚函数A::aa()和B::bb(),类B的大小等于char k[3]的大小加上一个指向虚函数表指针vptr的大小,考虑内存对齐为8。但是这里有一点,当class B是public virtual A,这样的话sizeof(B)就是16除了需要一个指向虚继承父类的指针之外,由于父类的虚函数是aa(),子类的虚函数是bb(),所以好像是B里面建了两个虚表,一个是继承A类的aa(),一个是B类的bb(),如果A和B里面的虚函数都是aa的话,这个B的大小将会是12.

    • 虚继承
    [cpp] 
    #include<iostream> 
    using namespace std; 
    class A 

    public: 
        virtual void aa(){} 
    private: 
        char k[3]; 
    }; 
    class B: virtual public A 

    public: 
        virtual void bb(){} 
    }; 
    int main() 

        cout<<"A's size is "<<sizeof(A)<<endl; 
        cout<<"B's size is "<<sizeof(B)<<endl; 
        return 0; 

    vs和gcc下
    执行结果:

    A's size is 8
            B's size is 12
    说明:类B里包含,继承的char k[3],继承的虚函数,类B的虚函数表里有A::aa(),因为是虚继承,还有一个指向父类的指针,该指针为指向虚基类的指针(Pointer to virtual base class)。考虑内存对齐,总大小为12。这里要特别指明一下,在windows下,B's size is 16,貌似在windows里虚继承还会有一个4字节的什么东西的这个应该和编译器有关系了。

    • 多重继承
    #include <iostream>
    using namespace std;
    class A
    {
        char k[3];
        public:
        virtual void aa(){};
    };
    class B
    {
        char q[3];
        public:
        virtual void bb();
    };
    class C: public A,public B
    {
        char j[3];
        public:
        virtual void cc(){};
    };
    int main()
    {
        cout<<"sizeof(A):"<<sizeof(A)<<endl;
        cout<<"sizeof(B):"<<sizeof(B)<<endl;
        cout<<"sizeof(C):"<<sizeof(C)<<endl;
        return 0;
    }

    像这种继承方式,在类C中会维护两个虚函数指针,第一个指向第一个基类的虚函数表(并且带上在类C中定义的虚函数),第二个指针指向第二个基类(B)的虚函数表...其他的类似。


    综合例子:

    #include <iostream>
    using namespace std;
    class A
    {
    char k[3];
    public:
     virtual void f(){};
    };
    class B : public virtual A
    {
        char i[3];
    public:
     virtual void f1(){};
    };
    class C: public virtual  A{
     //virtual void f(){};
     char j[3];
     public:
     virtual void t(){};
    };
    class D: public B,public C
    {
        char g[3];
        public:
        virtual void s();
    };
    int main()
    {
        cout<<sizeof(A)<<endl;
       cout<<sizeof(B)<<endl;
       cout<<sizeof(C)<<endl;
       cout<<sizeof(D)<<endl;
      return 0;
    }

    最后得到的结果是  8 16 16 28 (windows里是8 20 20 36,参照上述虚继承子类和父类续函数不一样导致的)

    最主要的是sizeof(D): 4个char数组,对齐后是16,又是多重继承,那么有两个虚函数表的指针,又需要维护一分A类的指针,那么是16+4*2+4=28...采用虚继承,目的就是为了解决二义性和减小内存开销,所以在D中只维护一份A的指针便可。


    在来插一句,有很多同学都觉得很奇怪,为什么类里面成员函数不占内存,其实成员函数和普通函数一样的都在内存,只不过分配在代码段而已,所以sizeof没有计算出来;


    展开全文
  • c++ class对象默认不一定为NULL

    c++ class对象默认不一定为NULL


    而后有函数代码为:

    if (a == NULL) 

    a = ...

    可能就是由于这里的a不定值,而导致后面的使用出现段错误。这会导致这种现象随机出现,会变得难发现问题根源。

    展开全文
  • C++ class实现链表

    千次阅读 2018-04-03 19:52:08
    #include &lt;iostream&gt;#include &lt;cstring&gt;#include&lt;cstdlib&...class LinkNode{ private: char m_name[20]; int m_age; LinkNode *m_next; public: Lin...
    #include <iostream>
    #include <cstring>
    #include<cstdlib>

    using namespace std;

    class LinkNode
    {
        private:
          char m_name[20];
          int m_age;
          LinkNode *m_next;

        public:
          LinkNode();
          LinkNode(char *name, int age);
          void SetNext(LinkNode *n);
          LinkNode *GetNext();
          char *GetName();
          int GetAge();
          ~LinkNode();

    };

    class LinkList
    {
        private:
          LinkNode *m_first;
          int m_sum;

        public:
          LinkList();
          void Init();
          void List();
          void Insert();
          void Delete();
          void Show();
          void Search();
          ~LinkList();
    };

    //关于节点的操作
    LinkNode::LinkNode()
    {
        cout << "NULL" << endl;
    }

    LinkNode::LinkNode(char *name, int age)
    {
        strcpy(m_name, name);
        m_age = age;
        m_next = NULL;
    }

    void LinkNode::SetNext(LinkNode *n)
    {
        m_next = n;
    }

    LinkNode *LinkNode::GetNext()
    {
        return m_next;
    }

    char *LinkNode::GetName()
    {
        return m_name;
    }

    int LinkNode::GetAge()
    {
        return m_age;
    }

    LinkNode::~LinkNode()
    {
        m_age = 0;
    }

    //关于链表的操作
    void LinkList::Show()
    {
        cout << "Please make your desion !" << endl;
        cout << "1、 Insert" << endl;
        cout << "2、 List" << endl;
        cout << "3、 Delete" << endl;
        cout << "4、 Exit" << endl;
    }


    LinkList::LinkList()
    {
        m_first = NULL;
        m_sum = 0;
    }

    LinkList::~LinkList()
    {

    }

    void LinkList::Init()
    {
        m_first = new LinkNode;//new 返回地址
    }

    void LinkList::Insert()
    {
        char name[20];
        int age;
        LinkNode *p = m_first;

        cout << "Please input name :" << endl;
        cin >> name;
        cout << "Please input age :" << endl;
        cin >> age;

        LinkNode *s = new LinkNode(name, age);

        for (int i = 0; i < m_sum; i++)
        {
            p = p->GetNext();
        }

        p->SetNext(s);
        m_sum++;
    }

    void LinkList::Delete()
    {
        char name[20];
        cout << "Please input name that you want to delete !" << endl;
        cin >> name;

        LinkNode *p = m_first;
        LinkNode *q = NULL;

        while (p != NULL && strcmp(p->GetName(), name) != 0)
        {
            q = p;
            p = p->GetNext();
        }

        if (p == NULL)
        {
            cout << "This name do not exsists !" << endl;
        }

        if (strcmp(p->GetName(), name) == 0)
        {
            q->SetNext(p->GetNext());
            delete p;
        }
        m_sum--;
    }

    void LinkList::List()
    {
        LinkNode *p = m_first->GetNext();
       
        while(p!=NULL)
        {
            cout << p->GetName() << "    " << p->GetAge() << endl;
            p = p->GetNext();
        }
    }

    int main(int argc, char const *argv[])
    {
        int choice;

        LinkList L;
        L.Init();

        while(1)
        {
            L.Show();
            cin >> choice;
            switch (choice)
            {
            case 1:
                L.Insert();
                break;
            case 2:
                L.List();
                break;
            case 3:
                L.Delete();
                break;
            case 4:
                exit(1);
                break;
            }
        }
        return 0;
    }
    展开全文
  • c++ class function const

    千次阅读 2016-12-14 11:01:44
    class A { public: void modify(int n); };实际的modify相当于是void modify(A *this, int n), 这里传递的是一个A的指针类型,但这也意味着这个modify函数可能会对成员变量进行修改。 而将代码修改为: class A ...

    const除了可以修饰变量外,其还可以在类函数的末尾添加const

    一般的成员函数如:

    class A {
     public:
        void modify(int n);
    };
    实际的modify相当于是void modify(A *this, int n),

    这里传递的是一个A的指针类型,但这也意味着这个modify函数可能会对成员变量进行修改。

    而将代码修改为:

    class A {
     public:
        void modify(int n) const;
    };
    那么modify相当于是void modify(const A *this, int n),

    即这里的this是指向const A的,因此该方法不能通过this来对本对象的变量进行修改


    那么下面的代码是否能成功执行呢?:

    class A {
     public:
        void modify(int n) const {
            num = n;
        }
     private:
        int num;
    };
    
    int main() {
        A a;
        a.modify(3);
        return 0;
    }
    这里是不能成功执行的,

    首先由上面的方法,我们可以知道,void modify(int n) const实际是void modify(const A *this, int n),

    那么整个方法就相当于为:

    void modify(const A *this, int n) {

    this->num = n;

    }

    这显然是不对的


    接着下面这份代码是否能成功执行呢?:

    class A {
     public:
        void modify(int n) {
        }
        void modify1(int n) const {
        }
    };
    
    int main() {
        const A a;
        a.modify(3);
        a.modify1(3);
        return 0;
    }
    这里的a.modify(3)是错误的,而a.modify1(3)是正常执行的

    还是将代码还原相等的代码

    void modify(int n)->void modify(A *a, int n) {}

    void modify1(int n) const -> void modify(const A *a, int n) {}

    而const A a,是const A类型,而c++中是不允许将const T*转换给T*的(除了用const_cast<T*>),那么自然对于void modify(int n)是错误的

    而void modify1(int n) const是正确的



    展开全文
  • C++ class friend

    千次阅读 2011-09-02 09:18:52
    class A; class B; class A { public: explicit A( int a ); ~A(); friend class B; private: int aa; }; A::A( int a ) { aa = a; } A::~A()
  • C++ class实例的内存结构

    千次阅读 热门讨论 2008-02-14 20:08:00
    C++ class实例的内存结构  Author:zfive5(zidong) Email:zfive5@yahoo.com.cn   引子   这些天让一些概念和算法烦得不知所措,只能听从佛祖教诲的:放下,然后上csdn去,看了两篇关于c++的文章,这个年头,...
  • C++ class内定义struct

    千次阅读 2018-01-31 08:58:40
    class CYuImageControl { DECLARE_DYNAMIC(CYuImageControl) public: …… //定义struct struct YuMarkPoint { double x; double y; }; //使用struct std::vector m_vMarkPoints; } 如上,若一个...
  • class A{ public: B* m_; } 这样会编译出错,因为B没有定义 #include "B.h" class A{ public: B* m_; } 但是这样,一旦B的定义修改,那么A.h也就会重新编译,导致所有用到A.h的文件也需要重新编译...
  • C++ class中的静态(static)成员

    万次阅读 2007-04-09 00:24:00
    C++ class中的静态(static)成员(1) 静态数据成员 ①一般地静态数据成员在该类定义之外被初始化,如同一个成员函数被定义在类定义之外一样。在这种定义中的静态成员的名字必须被其类名限定修饰,例如下面是_...
  • 转自 :... //declare c++ impl for Obj-C++ #ifdef __cplusplus class gp_mailer; #endif //declare obj-c impl #ifd
  • C++ class 中使用CUDA(包含texutre 2d的使用)

    千次阅读 热门讨论 2008-12-06 03:20:00
    一直想写一下global内存访问的文章,但是最近的事情太多,哎昨天。。。,今天的一篇paper也被拒了~~哎-- 不过收到一个QQ群朋友...晚上熬夜写了一个简单的C++ class 封装CUDA的demo,里面涉及到了texture的使用,希
  • How to export C++ class from dll

    千次阅读 2014-03-11 23:04:50
    原文来源: ...   译文来源:http://blog.csdn.net/clever101   C++语言毕竟能和Windows DLLs能够和平共处。   介绍    自从Windows的开始阶段动态链接库(DLL)就是Windows平台的一个组成
  • C++ class成员函数的奇葩用法

    千次阅读 2014-03-04 00:44:27
    是什么呢,就是类对象被释放后,还可以访问class成员函数,因为编译过了,运行中没有check null就会直接调用,下面我们可以看看奇葩的两种用法。 #include class test{ public: void print(){ printf("%s\...
  • C++ Class incomplete type is not allowed

    千次阅读 2013-07-18 16:00:35
    哈哈,居然是 没有加头文件!!!!
  • class Integer { private: int _num; public: //构造函数 Integer(int num) { _num = num; } //计算当前Integer 和 b之间的最大公约数 int gcd(Integer b) { int temp; if (_num<b._nu
  • How to Marshal a C++ Class

    千次阅读 2008-07-02 22:23:00
    Download source files - 16.4 KB IntroductionI recently needed to marshal some legacy C++ classes into a C# project on which I was working. Microsoft provides well documented means to marsh
  • #include ...class Integer{ private: int _num; //getLength()函数获取_num长度 int getLength(){ int size=0; while(_num>0){ size++; _num/=10; } return size; } public: //I
  • C++实现新的class有一些习俗,比如会提供一个 print(ostream & out)的公开的成员函数,例子如下 class Employee { public: void print(ostream& out) const { out ; } private: string name;
  • Environment: Managed C++, C#, .NET Framework 1.1 Introduction Did you ever face the challenge of ca
  • Cython:class 和 cdef class,使用 C++ class 和 cdef class class 定义属性变量比较自由,cdef class 可以定义 cdef class 使用 __init__ 初始化,cdef class 在使用 __init__ 之前用 __cinit__ 对 C 相关的参数...
  • C++ Friend class

    千次阅读 2014-04-14 23:09:04
    Here again, to learn the friend class in C++. And here is a demo for a better understanding. The demo is mainly to summary t
  • c++class

    千次阅读 2018-05-04 14:15:30
    一、定义 class是类定义时的关键字,和c语言中的struct很像。 二、使用 class Teacher { public: int age; char name[10]; private: protected : }; public...
  • C++class的简单使用

    万次阅读 2016-07-30 21:37:45
    C++class的简单使用

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 90,454
精华内容 36,181
关键字:

c++class

c++ 订阅