C++父类为虚函数(转)

转自https://blog.csdn.net/shltsh/article/details/45999727

C++中, 一旦某个成员函数在基类中声明为虚函数,则它在所有的子类中都会成为虚函数。换言之,如果应该在基类中声明了某个函数为虚函数,则无需在子类中使用关键字virtual再去声明函数。

可以参考: http://www.umsl.edu/~subramaniana/virtual2.html


例如,下面程序中,B::fun() 会自动成为一个虚函数

#include<iostream>
 
class A
{
public:
  virtual void fun()
  {
    std::cout << "A::fun() called \n";
  }
};
 
class B : public A
{
public:
  void fun()
  {
    std::cout << "B::fun() called \n";
  }
};
 
class C : public B
{
public:
  void fun()
  {
    std::cout << "C::fun() called \n";
  }
};
 
int main()
{
  C c;       // C的对象
  B *b = &c; // 类型为B*的一个指针,指向对象c
  b->fun();  // 这行代码会打印 "C::fun() called"
 
  A *a = &c;
  a->fun();  //这行代码会打印 "C::fun() called"
 
  return 0;
}

输出:C::fun() called
C::fun() called

发布于
归类为C++

VirtualBox后续

昨天我发布的文章,今天有了后续,在Intel推送了27.20.100.9168驱动后,问题已经得到了解决。显然双方一起解决了该问题,虽然有些慢。这次我是被打脸了,不过这样的打脸多一些还是不错的。

发布于
归类为默认

VirtualBox更新依旧没有解决问题

昨天VirtualBox终于更新了6.1.18版,然而依旧没有解决Intel显卡某驱动之后会导致3d加速无效,并在开启3d加速的前提下对虚拟机重启时会崩溃的问题。也许开源杀手Oracle已经打算把VirtualBox弄死了?

发布于
归类为默认

C++多继承,指针问题

C++中多继承的派生类最开始的位置是第一个基类,其后才是第二三四…个基类。所以派生类对象后面的基类的地址与派生类地址不同,但在将派生类地址赋值给基类指针时会自动转换。

#include <iostream>
using namespace std;
class A
{
    public:int a;
};
class B
{
    public:int b;
};
class C : public A, public B
{
    public:int c;
};
int main()
{
    C c;
    A *pa=&c;
    B *pb=&c;
    C *pc=&c;
    cout<<pa<<endl<<pb<<endl<<pc<<endl;
    return 0;
}

以上代码的某次运行结果为

0x7ffffffedc8c
0x7ffffffedc90
0x7ffffffedc8c

发布于
归类为C++

教训,反省

显然,我应该遵循在理智时期就想到的策略——不应和感情经验丰富的人产生超越友谊的关系,更不应对其抱有认真的期待。但是,我作为愚蠢的人类中的一员,在荷尔蒙的作用下,我将此抛掷脑后。此为重大教训,日后需谨记。

嗯,今天发现她把我微博取关并移除了。有点难受,有点生气,不过仔细想想她不配。也算丢掉最后一点念想了吧,此事算彻底了结了。

C++初始化列表与类内初始化

类内初始化可使用{},=,不可使用(),如

class test2
{
public:
    int c=6;//正确
    int d{7};//正确
    int e(8);//错误
};

初始化列表可使用{},(),不可使用=,如

class test2
{
public:
    test2(int h, int z) : c(h), d{z}
          //不可使用 c=h
    {
        cout << h << endl;
        cout << z << endl;
    };
};

一个成员同时在类内初始化与初始化列表时,实际结果表明初始化列表生效

#include <iostream>
using namespace std;
class test2
{
public:
    int c = 6;
    int d = 7;
    test2(int h, int z) : c(h), d{z}
    {
        cout << h << endl;
        cout << z << endl;
    };
};
int main()
{
    test2 a{10, 19};
    return 0;
}

以上代码输出10 19。

发布于
归类为C++

B:魔兽世界之一:备战

http://cxsjsxmooc.openjudge.cn/test/B/

系统关闭,未测试

#include <iostream>
#include <iomanip>
using namespace std;
class headquarters;
extern int Time;
class warrior
{
private:
    int num;
    const int life;

public:
    friend class headquarters;
    const int id;
    const static char name[][10];
    static int lifes[];
    warrior *next;
    warrior(int _id, int _life, int _num = 0) : id(_id), num(_num), life(_life), next(NULL){};
    bool create(int &w)
    {
        if (w >= life)
        {
            w -= life;
            num++;
            return true;
        }
        else
            return false;
    }
};
class headquarters
{
private:
    int life;
    warrior *pp;
    const int *order;
    const char *color;
    bool stop;
    int num;

public:
    headquarters(int _life, const int _order[], const char *_color) : pp(NULL), life(_life), order(_order), color(_color), stop(false), num(0)
    {
    }
    ~headquarters()
    {
        while (pp != NULL && pp->next != pp)
        {
            warrior *temp;
            temp = pp->next->next;
            delete pp->next;
            pp->next = temp;
        }
        delete pp;
    }
    void add_node(int _id)
    {
        warrior *temp = new warrior(_id, warrior::lifes[_id]);
        if (pp == NULL)
        {
            pp = temp;
            pp->next = pp;
        }
        else
        {
            temp->next = pp->next;
            pp->next = temp;
            pp = temp;
        }
    }
    bool making()
    {
        if (stop)
            return false;
        pp = pp->next;
        if (pp->create(life))
        {
            num++;
            cout << setw(3) << setfill('0') << Time << ' ';
            cout << color << ' ' << warrior::name[pp->id] << ' ' <<num <<' '<<"born with strength "<<pp->life<<","<< pp->num <<" "<<warrior::name[pp->id]<<" in "<<color<<" headquarter"<< endl;
            return true;
        }
        else
        {
            warrior *temp = pp->next;
            while (temp != pp)
            {

                if (temp->create(life))
                {
                    num++;
                    cout << setw(3) << setfill('0') << Time << ' ';
                    pp = temp;
                    cout << color << ' ' << warrior::name[temp->id] << ' ' <<num<<' '<<"born with strength "<<temp->life<<"," << temp->num <<" "<<warrior::name[temp->id]<<" in "<<color<<" headquarter"<<endl;
                    return true;
                }
                temp = temp->next;
            }
            stop = true;
            cout << setw(3) << setfill('0') << Time << ' ';
            cout << color << " headquarter stops making warriors" << endl;
            return false;
        }
    }
};
const char warrior::name[][10]{"dragon", "ninja", "iceman", "lion", "wolf"};
int warrior::lifes[5]{0};
const int _order[2][5]{{2, 3, 4, 1, 0}, {3, 0, 1, 2, 4}};
const char color[][5] = {"red", "blue"};

int Time = 0;
int main()
{
    int n;
    cin >> n;
    for (int j = 1; j <= n; j++)
    {
        cout << "Case:" << j << endl;
        int h_life;
        cin >> h_life;
        for (int i = 0; i < 5; i++)
        {
            cin >> warrior::lifes[i];
        }
        headquarters red(h_life, _order[0], color[0]);
        headquarters blue(h_life, _order[1], color[1]);
        for (int k = 0; k < 5; k++)
        {
            red.add_node(_order[0][k]);
            blue.add_node(_order[1][k]);
        }
        for (Time = 0;; Time++)
        {

            bool a, b;

            a = red.making();

            b = blue.making();
            if (!(a || b))
                break;
        }
    }
    return 0;
}

发布于
归类为C++

校门外的树,允许较大l解法,C++版

http://pkuic.openjudge.cn/hw05/8/

#include <iostream>
using namespace std;
int main()
{
    int l, m;
    cin >> l >> m;
    int a[2][m] = {0};
    int k = 0;
    for (int i = 0; i < m; i++)
    {
        cin >> a[0][i] >> a[1][i];
        if (a[0][i] > a[1][i])
            swap(a[0][i], a[1][i]);//防止输入数据反向
        if (a[1][i] > l)
            a[1][i] = l;//忽略掉右侧超过l的部分
        if (a[0][i] > l)
        {
            i--;
            m--;
        }//忽略掉左侧超过l的输入
    }
    for (int i = 0; i < m; i++)
    {
        for (int j = i + 1; j < m; j++)
        {
            if (a[0][i] <= a[1][j] && a[0][j] <= a[1][i])
            {
                a[0][i] = min(a[0][i], a[0][j]);
                a[1][i] = max(a[1][i], a[1][j]);
                swap(a[0][j], a[0][m - 1]);
                swap(a[1][j], a[1][m - 1]);
                m--;
                j=i;
            }
        }
    }//合并重复砍掉的树
    for (int i = 0; i < m; i++)
    {
        k += (a[1][i] - a[0][i] + 1);
    }//计算砍掉的数
    l = l - k + 1;
    cout << l << endl;
    return 0;
}
发布于
归类为C++

C语言指针数组,数组指针小记

谈一些浅显的理解,如有错误欢迎指正

只有在强制转换类型时,才是变量类型结合后面的*,例如

a=(int*)malloc(5*sizeof(int));

在其他情况下都是后面变量结合前面的*,如声明指针变量时

int *p;
int (*p);//正确等价

(int*) p;//错误示范!!

在声明函数时可以不写形参,可以理解为隐藏了而并非没有,形参如果有指针理解为*与未写的参数结合

int test(int *);
int test(int *p);
int test(int (*));
int test(int (*p));//以上声明方式皆正确等价

int test((int*)p);
int test((int*));//错误示范!!

对于typedef定义指针类型时*同样要放到类型前面,如

typedef struct Lnode
{
data;
struct Lnode *next;
}*linklist;

当指针、数组、函数相结合时,先结合什么就是什么,如

int *p[4];
int *(p[4]);

以上由于[]优先级比*高,二者等价,因为先结合[]所以p是个数组!!!然后每个数组的元素时int型指针

int (*p)[4];

以上先结合*,所以p是个指针,指向4元素int类型数组

对于指针与函数,如

int *test(int);
int (*test(int)); //以上表示返回值是int型指针的函数

int (*test)(int); 
int ((*test)(int));//指向函数的指针

(int*) (test(int));//错误示范!!!

前两个当中test先和后面的(int)结合,所以test本身是函数,然后和前面结合,返回值为int型指针

第三、四个test先和*结合,所以test是指针,再和后面结合表示函数,返回值为int型

最后一个是错误示范

发布于
归类为C