English 中文(简体)
a. 用作基地地图集
原标题:Use a class as a BaseClass
  • 时间:2012-05-06 12:25:36
  •  标签:
  • c++

我有:

class BASE{
public:
    virtual void func1() = 0;
};

然后,我有一些衍生课程,例如:

class Derived1 : public BASE{
public:
    void func1() {...implementation....}
};

class Derived2 : public BASE{
    public:
        void func1() {...implementation....}
    };

在我主要想做的是(假冒代码):

if ( cond ){
   BASE b := new Derived1
}
else{
   BASE b := new Derived2
}
b.func1();

因此,援引的 func(1)职能是专为衍生类别的职能。

我努力做到:

BASE b = new Derived1();

但汇编者抱怨。

能否在C++中做到这一点? 如何?

最佳回答

这样做有两个途径:

  • 1. 使用一组基类:

    <代码>Base *b = 新的衍生物1;

  • 如果你想在复印件建筑上产生一个衍生物,则使用最先进的基类:

    <代码>Base const& b = Derived;

  • 1. 如果你想指定别处生产的衍生物,则使用非最基本基准类别:

    Derived d; Base& b = d;

Nits:

  • In order to inherit, you need to specify this in the class definition:

  • 你们的职能必须具有回报价值。

    class B{ public: virtual void func() = 0; };

问题回答

很显然,你再次使用垃圾收集的垃圾填埋场语言,如 Java。 从这个角度看,回答这个问题可能是有益的。

当你写文章时

Base b = new Derived1();

在 Java,情况如下:

  1. A pointer "&b" (I ll call it β) to a generic Base object is allocated on the stack
  2. A new Derived1 object (I ll call it d) is allocated on the heap
  3. β is set to point at the Derived object.

你很容易在 Java离开的原因是有一个垃圾收集器。 只要<条码>β<>>>><>>>> /代码>在“条码”和“条码”(<>d上,该数值就具有任何效力,因为当时《GC》知道<条码>d<<>>>>> > ><<<>>>> > > > 仍在使用之中。 但只要无点人提及<条码>d,则(例如,由于你宣布<条码>b的功能,则允许GC释放由<条码>d占用的空间。 简便,但垃圾收集有severalvant ,我们在C++中并不需要。

因此在C++中,如果你做这样的事情的话。

Base* b = new Derived1();

直接与 Java版本相对应的是:当b>离开范围时,再不提<>d,但仍然位于[上。 页: 1

delete b;

(指出这具有你可以准确确定何时将其删除的巨大优势,而停车场收集器可以长时间无用地将其抛在一边,并且只有在你开始忘掉记忆时才会抹去。) 但这再次是不够的:与垃圾收集器不同,你的方案并不自动知道<条码>b>至<条码>的点。 物体而不是Base Object, so delete 删除时将考虑其处理。 页: 1 但很容易做到:在<条码>中包含一个虚拟脱轨器。 页: 1

class Base{
 public:
  virtual void func1() = 0;
  virtual ~Base() {}  
};


现在,用手方式删除所有物品显然是危险的:如果你忘记这样做的话,你就会有记忆泄露,即只要你的节目运行,就将物体never除去。 因此,应当使用smart Pointers而不是简单的C类点,这样就自动删除了它们在离开范围时指明的物体。 在C++11中,这些定义在标准图书馆中界定(标题<memory>)。 你们

std::unique_ptr<Base> b(new Derived1());

现在,在<条码>b离开范围时,自动删除<条码>。

在所有这些例子中,将虚拟功能称作“虚拟功能”以同样方式运作:

b->func1();

用户点(或参考),否则,你的物体将仅复制成普通BASE:

BASE* b = new Derived1;
b->func1();

// later...
delete b;

此外,不要忘记使你的逃兵成为本案的虚拟人物。

由于整个新的/多功能事物只是为了让多吗? 人们现在往往使用智能识别器:

std::shared_ptr<BASE> b=std::make_shared<Derived1>();
b->func1();

你试图把点子指定给正常物体。

new Derived1()

This expression returns a pointer. You ll either have to make BASE a pointer (BASE *), or just create it on the stack (preferable, Base b;). In this case though, you d need pointers (or references) to convert between classes.

而且,你也可以在一纸空话中制造该物体,因为这样,当你想在晚些时候使用该物体时,该物体就会失去范围。

你可以做些什么:

BASE *b;

if (cond)
    b = new Derived1();
else
    b = new Derived2();

b->func1();

当然,你必须记住<代码>delete。 只考虑使用智能点。

使用点人(及其陷阱)已包括在内,因此,我向大家展示了如何在没有动态记忆分配的情况下使用多变形态,这或许证明我对它的想法是 her。

首先,请见您的原始法典,并编成:

void foo(bool const cond) {
    Base* b = 0;
    if (cond) { b = new Derived1(); }
    else      { b = new Derived2(); }

    b->func1();
    delete b; // do not forget to release acquired memory
}

http://www.ohchr.org。

节目设计员发展过程中的下一个合乎逻辑的步骤是使用智能点,避免撰写<条码>delete(delete,只供开端人和专家图书馆作者使用):

void foo(bool const cond) {
    std::unique_ptr<Base> b;
    if (cond) { b.reset(new Derived1()); }
    else      { b.reset(new Derived2()); }

    b->func1();
}

这当然还需要virtual destructor for Base

让我们认识到,这一职能有两个方面:

  • choose a class given a condition
  • do some work on the instance produced

我们可以打破这一僵局,例如通过提取建筑工作:

std::unique_ptr<Base> build(bool const cond) {
    if (cond) { return { new Derived1() }; }
    return { new Derived2() };
}

void foo(bool const cond) {
    std::unique_ptr<Base> b = build(cond);
    b->func1();
}

这是大多数人做的事。

我声称还有另一种可能性,即我们不孤立建筑,而是能够孤立实际工作:

void dowork(Base& b) { b.func1(); /* and perhaps other things */ }

void foo(bool const cond) {
    std::unique_ptr<Base> b(cond ? new Derived1() : new Derived2());
    work(*b);
}

我们实际上可以采取进一步步骤:

void foo(bool const cond) {
    if (cond) {
        Derived1 d;
        work(d);
    } else {
        Derived2 d;
        work(d);
    }
}

www.un.org/spanish/ecosoc 多种形态不需要有活力的记忆分配。

你们知道这最后的一个例子是:

  • it works perfectly fine without C++11 move semantics
  • it does not require having a virtual destructor in Base

你们是否忘记了这一点?

class Derived1 : public BASE
{
};

至少,我看不见你的法典,即BASE的阶层。

如果功能签名相同,或许在这种情况下,接口申报更为合适......因为每一类别都实施接口,并宣布变数为您宣布的接口类型......





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签