精华内容
下载资源
问答
  • 虚基类初始化

    2017-05-02 17:14:43
    使用虚基类时,虚基类时被共享的,也就是...C++标准中选择在每一次继承子类中都必须书写初始化语句,但是虚基类初始化是由最后的子类完成,其他的初始化语句都不会调用。 class animal { public: void printanim

    使用虚基类时,虚基类时被共享的,也就是在继承体系中无论被继承多少次,对象内存模型中均只会出现一个虚基类的子对象,即使共享虚基类。但是必须要有一个类来完成基类的初始化,同时还不能够重复进行初始化。C++标准中选择在每一次继承子类中都必须书写初始化语句,但是虚基类的初始化是由最后的子类完成,其他的初始化语句都不会调用。

    class animal
    {
    public:
    void printanimal()
    {
    cout << "class animal" << endl;
    }
    animal(int age)
    {
    this->age = age;
    }
    int age;
    };
    //每一个继承子类中,都必须写初始化语句
    class horse:virtual public animal
    {
    public:
    horse():animal(1){}//不调用
    };
    class donkey:virtual public animal
    {
    public:
    donkey() :animal(2) {}//不调用
    };
    class mule:public horse,public donkey
    {
    public:
    mule() :animal(3) {}//调用
    };
    void test()
    {
    mule m1;
    cout << m1.age << endl;//输出3
    }

    展开全文
  • C++ 虚基类初始化

    千次阅读 2015-04-23 10:47:04
    如果一个派生类有多个基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接...对基类的派生类:在最后的派生类中不仅要负责对其直接基类进行初始化,还要对虚基类初始化。 代码一: #inclu

    如果一个派生类有多个基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接数据成员的多份同名成员。

    使用虚基类可使最终的派生类只保留共同基类的一份同名成员。

    一般情况下,派生类的构造函数只需负责对其直接基类初始化,再由直接基类负责对间接基类初始化。

    对虚基类的派生类:在最后的派生类中不仅要负责对其直接基类进行初始化,还要对虚基类初始化。


    代码一:

    #include <iostream>
    using namespace std;
    
    class A
    {
    	public:
    	A(){cout<< 'a';}
    	int a;
    };
    
    class B: public A
    {
    	public:
    	B(){cout<< 'b';}
    	int b;
    };
    
    
    class C: public A
    {
    	public:
    	C(){cout<< 'c';}
    	int c;	
    };
    
    class D: public B, public C
    {
    	public:
    		D(){cout<< 'd';};
    	int d;	
    };
    
    int main()
    {
    	D d;
    	return 0;
    }
    //abacd 

    程序输出abacd,调用类D的构造函数会先调用类D的直接基类的构造函数,因为按基类出现的顺序调用构成函数,所以先调用类B的构造函数,同理:调用类B的构造函数,先调用类A的构造函数,所以输出abacd


    代码二:

    <pre name="code" class="cpp">#include <iostream>
    using namespace std;
    
    int t= 0;
    
    class A
    {
    	public:
    	A(){cout<< 'a'; t++;}
    	int a;
    };
    
    class B: virtual public A
    {
    	public:
    	B(){cout<< 'b';}
    	int b;
    };
    
    
    class C: virtual public A
    {
    	public:
    	C(){cout<< 'c';}
    	int c;	
    };
    
    class D: public B, public C
    {
    	public:
    		D(){cout<< 'd';};
    	int d;	
    };
    
    int main()
    {
    	D d;
    	cout<< t;
    	return 0;
    }
    //abcd1


     
    
    类D的构造函数通过初始化调用了虚基类的构造函数A,然后再调用类B和类C的构造函数。

    那么这里类B和类C的构造函数会不会调用虚基类的构造函数A呢?

    不会, 因为C++编译相同只执行最后的派生类对虚基类的构造函数的调用,而忽略基类的其他派生类对虚基类的构造函数的调用

    展开全文
  • 运行环境:macOS shell 代码:#include #include #include using namespace std;class base { protected: int x; public: base(int x1) { x = x1; cout<<"constr

    运行环境:macOS shell
    代码:

    #include <iostream>
    #include <iomanip>
    #include <string>
    using namespace std;
    
    class base
    {
    protected:
        int x;
    public:
        base(int x1)
        {
            x = x1;
            cout<<"constructing base, x = "<<x<<endl;
        }
    };
    
    class base1 :  virtual public base
    {
        int y;
    public:
        base1(int x1, int y1):base(x1)
        {
            y = y1;
            cout<<"constructing base1, y = "<<y<<endl;
        }
    };
    
    class base2 : virtual public base
    {
        int z;
    public:
        base2(int x1, int z1):base(x1)
        {
            z = z1;
            cout<<"constructing base2, z = "<<z<<endl;
        }
    };
    
    class derived:public base1, public base2
    {
        int xyz;
    public:
        derived(int x1, int y1, int z1, int xyz1):base(x1),base1(x1,y1),base2(x1,z1)
        {
            xyz = xyz1;
            cout<<"constructing derived, xyz = "<<xyz<<endl;
        }
    };
    
    int main ()
    {
        derived obj(1,2,3,4);
        return 0;
    }

    运行结果:
    这里写图片描述

    展开全文
  • C++ 成员和基类初始化

    千次阅读 2018-09-06 20:37:11
    C++ 成员和基类初始化 class Club { struct Date { int year; int month; int day; Date(int y, int m, int d); } string name; vector&lt;string&gt; members;...

    C++ 成员和基类的初始化


    class Club
    {
        struct Date
        {
            int year;
            int month;
            int day;
            Date(int y, int m, int d);
        }
    
        string name;
        vector<string> members;
        vector<string> officers;
        Date founded;
    public:
        Club(const string& n, Date fd);
    };

    1. 成员初始化

    Club的构造函数接收两个参数。在构造函数的定义中,通过成员初始化列表给出成员的构造函数的参数:

    Club::Club(const string& n, Date fd)
        :name{n},founded{fd}
    {
        // ...
    }
    如果一个成员的构造函数不需要参数,就不必在成员初始化列表中提及此成员。
    
    • 类自身的构造函数在其构造函数体执行之前会先调用成员的构造函数。成员的构造函数按成员在类中的声明顺序调用,而不是按成员在初始化列表中出现的顺序。成员之间存在初始化依赖的时候需要注意成员的声明顺序

    • 内置类型成员需要显式初始化,隐式初始化的内置类型成员实际上是未初始化的

    • 一个构造函数可以初始化其类的成员和基类,但不会初始化 其成员或基类 的 成员或基类。也就是说类的成员初始化过程只会初始化一层成员(调用自己成员的构造函数),不会初始化成员的成员(不会调用自己成员的成员的构造函数)

    • 引用成员或者const成员必须初始化


    2.基类初始化器

    如果基类要求一个初始化器,就必须在构造函数中提供相应的基类的初始化器。如果希望进行默认构造,可以显式指出。

    class B1{ B1(); };        // 具有默认构造函数
    class B2{ B2(int); };     // 无默认构造函数
    
    struct D1 : B1,B2
    {
        D1(int i) : B2{i}{}   // 隐式使用B1{}
    };
    
    struct D2 : B1,B2
    {
        D2(int i){}           // 错误:B2没有默认构造,要求有一个int初始化器
    };

    基类按声明顺序进行初始化,建议按此顺序指定基类的初始化器。
    基类的初始化在成员之前,销毁在成员之后。


    3.委托构造函数

    class X
    {
        int a;
    public:
        X(int x){ if (0<x && x<=max) a=x; else throw Bad_X(x); }
        X() : X{42} {}
        X(string s) : X{to<int>(s)} {}
        // ......
    };

    使用一个成员风格的初始化器,但用的是类自身的名字(也是构造函数名),它会调用另一个构造函数,作为这个构造过程的一部分。
    如果一个构造函数在初始化列表中委托了其他构造函数,则该函数不能在初始化列表中出现任何成员初始化器


    4.类内初始化器

    可以在类声明中为非static数据成员指定初始化器:

    class A
    {
    public:
        int a{7};
        int b=77;
    };
    {}和=语法能用于类内成员初始化器,但()语法就不行
    

    默认情况下,构造函数会使用这种类内初始化器。
    与上面的代码效果等价如下:

    class A
    {
    public:
        int a;
        int b;
        A() : a{7},b{77} {}
    };

    类内初始化器的这种用法可以节省一些输入工作量,但真正的收益是在用于具有多个构造函数的复杂的类时,对同一个成员,多个构造函通常使用相同的初始化器。
    如果一个成员既被类内初始化器初始化,又被构造函数初始化,则只执行只执行后者的初始化操作


    5.static成员初始化

    一般来说,static成员声明充当类外定义的声明:

    class Node
    {
        //......
        static int node_count;    // 声明
    }
    
    int Node::node_count = 0;     // 定义

    但是,在少数简单的特殊情况下,在类内声明中初始化static成员也是可能的。条件是static成员必须是整型或枚举类型的const,或字面值类型的constexpr,且初始化器必须是一个常量表达式:

    class Curious
    {
    public:
        static const int c1 = 7;        // 正确
        static int c2 = 11;             // 错误:非const
        const int c3 = 13;              // 正确,但非static
        static const int c4 = sqrt(9);  // 错误:类内初始化器不是常量
        static const float c5 = 7.0;    // 错误:类内初始化成员不是整型(应使用constexpr而非const)
    }

    当(且仅当)使用一个已初始化成员的方式要求它像对象一样在内存中存储时,该成员必须在某处(唯一)定义,初始化器不能重复。

    展开全文
  • 1、虚基类的作用从上面的介绍可知:如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员。 在引用这些同名的成员时,必须在派生类...
  • c++之虚基类初始化

    2016-08-27 16:38:00
    C++虚基类构造函数下面文章详细介绍C++基,所谓C++虚基类:是由最派生类的构造函数通过调用虚基类的构造函数进行初始化的,但前提是要深入理解到底什么是C++虚基类,及他是怎么运行的。 前面讲过,为了初始化基类...
  • 初始化列表时,仅支持该类成员变量和基类构造函数初始化,基类的成员变量报错! #include<iostream> class Base { public: int m_value; }; class Son :public Base { public: Son() :m_value(value) //...
  • 派生类构造函数的参数初始化列表,为什么不能初始化基类的成员? 例如下面的是不可以的 class Rectangle : public Shape { public: Rectangle () : id(1234), name("Rectangle") { // id: 父类Shape...
  • 如果基类有私有成员,并且需要在派生类中的构造函数中初始化。这是会用到基类的复制构造函数。 有如下示例: #include "stdafx.h" #include <iostream> #include <string> using namespace std; ...
  • 一个class对象中的虚基类子对象虚基类子对象,布局不同。 非虚基类子对象如同它是派生类中的一个普通数据成员,可以出现多次: class A {memebers}; class B : public A { members }; class C : public A {...
  • 【C++】C++继承派生类、虚基类

    万次阅读 多人点赞 2018-06-07 18:46:17
    从已有的对象类型出发建立一种新的对象类型,使它部分或全部继承原对象的特点功能,这是面向对象设计方法中的基本特性之一。继承不仅简化了程序设计方法,显著提高了软件的重用性,而且还使得软件更加容易维护。...
  • 虚基类 :  如果某个派生类的部分或全部直接基类是从另一个共同的基类派生而来,在这些基类中,从上一级基类继承来的成员就有相同的名称,则在这个派生类中访问这个共同的基类中的成员时,可能会产生二义性,此时,...
  • 虚基类的作用

    千次阅读 2018-03-07 22:10:34
    1 概念 首先还是先给出虚继承和虚基类的定义。虚继承:在继承定义中包含了virtual关键字的继承关系;虚基类:在虚继承体系中的通过virtual继承而来的基类,需要注意的是:CSubClass : public virtual CBase {}; ...
  • C++抽象基类虚基类(C++ primer)

    千次阅读 2019-05-02 15:18:35
    c++ primer plus P556,虚基类 抽象基类(abstract base class,ABC) 抽象基类是解决如下问题: 加入现在需要开发一个图形类,表示圆与椭圆(注意,圆是一种特殊的椭圆)。所以初步考虑从椭圆类中派生出圆类。但是...
  • 继承和派生、虚继承和虚基类、虚基类和虚基类指针继承和派生继承概述继承基本概念派生类中的成员继承的内容派生类定义派生类访问控制对象构造和析构对象构造和析构的调用顺序继承中的构造和析构的调用规则调用子类...
  • 1、为什么要虚基类或者说继承: a、直接二义性可以用作用域与同名覆盖的方法来消除(看程序注释),但是间接二义性(同名数据成员在内存中同时拥有多个拷贝,同一个成员函数会有多个映射,多...
  • C++派生类中如何初始化基类对象

    千次阅读 2018-08-26 16:41:42
    问我一个问题,关于派生类中如何初始化基类对象,我在想派生类对于构造函数不都是先构造基类对象,然后在构造子类对象,但是如果我们在成员初始化列表先初始化派生类的私有成员,在函数内去调用基类的构造函数,能...
  • 派生类对象的构造函数初始化,构造函数在成员初始化列表中使用基类类名来调用特定的基类构造函数 V2(int &w,double &q):V1(w){} //v1是基类,这种情况初始化列表中是用基类名称 而一个类中包含其他类对象...
  • 在公用继承、私有继承保护继承中,只有公用继承能较好地保留基类的特征,它保留了除构造函数析构函数以外的基类所有成员,基类的公用或保护成员的访问权限在派生类中全部都按原样保留下来了,在派生类外可以调用...
  • 虚基类的概念及用法 如果派生类的全部或者部分基类有共同的基类,那么派生类的这些直接基类从上一级基类继承的成员都具有相同的名称,定义了派生类的对象后,同名数据成员就会在内存中有多份拷贝,同名函数也会有多...
  • 虚基类

    2020-06-18 19:23:37
    1.要使这个公共基类在派生类中只产生一个子对象,必须对这个基类声明为继承,使这个基类成为虚基类。 2. 虚基类用于有共同基类的场合 3. 声明虚基类的一般形式为: class 派生类名: virtual 继承方式 基类名 例:...
  • 虚基类(多重继承)

    2021-03-10 10:49:47
    多重继承容易出现的问题:命名冲突数据冗余问题。 #include <iostream> using namespace std; // 间接基类 class Base1 { public: int var1; }; // 直接基类 class Base2 : public Base1 { public: int ...
  • #include class A { int a; public: A(int x) { a=x; cout; } }; class B:virtual public A { public: B(int i):A(i) { cout; } }; class C:virtual public A ...
  • C++中虚基类

    2017-09-27 11:46:09
    虚基类虚基类概念...A是虚基类,B1B2继承自A,D继承B1B2,D中的数据就是来自A,B1,B2中的数据而无重复冗余。 而没有使用继承,D中的数据就包括了两份A类的数据。虚基类例子#include using namespace st
  • 7>在一个成员初始化列表中,同时出现对虚基类和虚基类构造函数的调用时,基类的构造函数先于非虚基类的构造函数执行。 8>虚基类并不是在声明基类时声明的,而是在声明派生类是,指定继承方式时声明的。因为...
  • 初始化列表和派生类构造函数中的基类参数表 引例   在图形这个抽象类上派生出矩形类和圆形类,两者都有计算对象周长的函数,并编写测试main()函数 使用初始化列表 #include<iostream> using namespace std; ...
  • C++之基类构造函数初始化

    千次阅读 2018-09-19 13:44:36
    定义一个基类初始化需要传入一个整数 class mybase { public: mybase(int iType); virtual ~mybase(); public: int m_iType; }; 在定义一个子类,继承于mybase class my:public mybase { public: my(); ...
  • 虚基类初始化与一般的多继承的初始化在语法上是一样的,但构造函数的执行顺序不同,主要有以下几点: 1.虚基类的构造函数的执行在非蕨类的构造函数之前。 2.若同一层次中包含多个虚基类,这些虚基类的构造函数...
  • 多继承与虚基类

    2021-04-25 14:53:54
    声明多个基类的派生类与声明单基派生类的形式相似,只需将要继承的多个基类使用逗号分隔即可。 已经声明了类X类Y,可以声明多重继承的派生类Z. class:public X,private Y{ //类z公有继承了类x,私有继承了类y 派生...
  • 在C++中,我们会遇到virtual这个关键字,但是它有两种含义:虚函数和虚继承,它们两个是完全无相关的两个概念。 什么是虚继承   虚继承是解决C++多重继承问题的一种手段,从不同途径继承来的同一基类,会在子类...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 183,022
精华内容 73,208
关键字:

虚基类和基类初始化列表