在基类中设置一些值后,是否可以设置指向派生类的指针?

时间:2015-06-06 13:03:04

标签: c++ class inheritance

我是c ++的新手(我正在使用visual studio 2013),我开始尝试使用类和继承。所以我提出了一个我找不到任何问题的问题。让我们说我们有这个课程:

for spike in self.overlapping_sprites:
    spike.handle_collide

有没有办法可以在main()中指定一个指向base的指针,设置值选择选择它是第一个还是第二个类?例如:

#include <iostream>
using namespace std;
class base{
protected:
     int var;
public:
     void setvalue(int);
     virtual void print();
};
class first:public base{
public:
    void print();
};
class second: public base{
public:
    void print();
};

这有可能吗? (正如我所说,我是c ++的新手所以如果您有任何疑问,请随时提出!) 谢谢!

5 个答案:

答案 0 :(得分:1)

对象的类型在构造中是固定的,永远不能更改。因此,对你的问题的直接回答是&#34; no&#34;。

但在这个框架内,你有很多权力。例如,您可以将三个类分成四个:三个只执行打印(BasePrinter,DerivedPrinter1,DerivedPrinter2)和其他只保存值并且没有任何虚拟方法的类。每次调用print()方法时,BasePrinter类都可以传递一个ValueHolder对象(通过const引用)。或者,每个ValueHolder都可以有一个指向BasePrinter对象的指针,并且每次传递所有必需的数据,使用一些(非虚拟)print()方法来完成所有这些转发。

答案 1 :(得分:1)

由于这是不可能的,唯一想到的是你以另一种方式解决问题,也许是使用一些很常见的设计模式

在这种情况下,鉴于您提供的信息很少,Factory pattern似乎是合适的。

#include <iostream>
using namespace std;

class base {
protected:
     int var;
public:
     void setvalue(int);
     virtual void print();
     static base* makeObject(int);
};

class first : public base {
public:
    void print();
};

class second : public base {
public:
    void print();
};

base* base::makeObject(int param) {
    base* ret = NULL;
    if(/* some condition based on params */) {
        ret = new first();
        ret->setvalue(0);
    } else if(/* some other condition */) {
        ret = new second();
        ret->setvalue(1);
    }
    return ret;
}

int main() {
    base *ptr = base::makeObject(...);
    base->print(); // use the correct member, based on which class I choosed
    return 0;
}

答案 2 :(得分:0)

您必须在创建对象时选择类型:

int main()
{
    base *ptr = new first; // here.
    ptr->setvalue(1);
    ptr->print(); // use first::print.
    delete ptr;
}

答案 3 :(得分:0)

不直接。创建对象时,需要指定其完整类型,以便C ++知道如何为您正确布局内存。

如果您确实需要稍后更改它,您始终可以创建一个新类(具有正确的派生类型)并使用原始基类对其进行初始化,然后删除原始类。这可能比您提出的方法稍慢(取决于类的最终复杂性),但它可以完成工作。

答案 4 :(得分:0)

由于您正在使用继承,因此最佳做法是在基类中定义虚拟析构函数。在定义复杂的类时,需要仔细清理。

int main(){
base *ptr = new base;
base->setvalue(1);
/* Here I choose if base is pointing to First or Second class*/
base->print(); // use the correct member, based on which class I choosed
return 0;}

你想做的事是不可能的。您必须按如下方式更改程序以避免编译错误。

base *ptr = new base;
ptr->setvalue(1);
ptr->print(); 
delete ptr;
return 0;

因为您的基指针ptr始终具有动态类型的类库。此代码始终调用base::print函数

如果您按如下方式定义ptr,则可以使用多态性。

  base * ptr = new first;
  ptr->setvalue(1);
  ptr-> print() 
  delete ptr

这里ptr首先有一个动态类型,它将调用函数first::print()