如何使用抽象类作为每个循环的索引变量的类型?

发布于 2025-02-02 02:20:24 字数 1404 浏览 0 评论 0 原文

我正在将我的 Java 程序翻译成 c ++ 。我遇到了一个问题,试图使用多态性 java 中的方式相同。

我的代码看起来像这样:


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

class Derived_1 : public Base
{
public:
    void print()
    {
        std::cout << "1" << std::endl;
    }
};

class Derived_2 : public Base
{
public:
    void print()
    {
        std::cout << "2" << std::endl;
    }
};

下一个是我尝试过的主要方法的两个版本,都给我编译器错误

1:

int main(int argc, char const *argv[])
{
    std::vector<Base> v;
    
    v.push_back(Derived_1());
    v.push_back(Derived_2());

    for(Base i: v)
    {
        i.print();
    }

    return 0;
}

错误:

object of abstract class type "Base" is not allowed:C/C++(322)
main.cpp(35, 14): function "Base::print" is a pure virtual function

2:

int main(int argc, char const *argv[])
{
    std::vector<Base*> v;
    
    v.push_back(new Derived_1());
    v.push_back(new Derived_2());

    for(Base* i: v)
    {
        i.print();
    }

    return 0;
}

错误:

expression must have class type but it has type "Base *"C/C++(153)

你们将如何解决这个问题?

I was translating a Java program of mine to C++. I got to a problem trying to use polymorphism the same way as in Java.

My code looks something like this:


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

class Derived_1 : public Base
{
public:
    void print()
    {
        std::cout << "1" << std::endl;
    }
};

class Derived_2 : public Base
{
public:
    void print()
    {
        std::cout << "2" << std::endl;
    }
};

The next are two versions of my main method that I have tried, both give me compiler errors:

1:

int main(int argc, char const *argv[])
{
    std::vector<Base> v;
    
    v.push_back(Derived_1());
    v.push_back(Derived_2());

    for(Base i: v)
    {
        i.print();
    }

    return 0;
}

Error:

object of abstract class type "Base" is not allowed:C/C++(322)
main.cpp(35, 14): function "Base::print" is a pure virtual function

2:

int main(int argc, char const *argv[])
{
    std::vector<Base*> v;
    
    v.push_back(new Derived_1());
    v.push_back(new Derived_2());

    for(Base* i: v)
    {
        i.print();
    }

    return 0;
}

Error:

expression must have class type but it has type "Base *"C/C++(153)

How would you guys solve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

等风也等你 2025-02-09 02:20:24

来自 java to c ++ ,有很多值得照顾的;特别是内存管理!

在第一个显示的情况下,您将对象切片。请参阅什么是对象切片?

为了访问虚拟函数,您应该使用过 std :: vector&lt; base*&gt; (即指针的向量 base )或 std :: vector&lt; std :: simolor_ptr&lt; base代码>或 std :: vector&lt; std :: shared_ptr&lt; base&gt;&gt; (即智能指针的向量 base )。

在您的第二个代码中,您的 v 是指向 base 指针的向量,这意味着您需要通过 - &gt; 操作员访问成员。

即,您应该已经访问了 print()如下:

i->print();
^^^

或者:

(*i).print();
^^^^^

另请注意:

  • 在您的第二种情况下,无论您 new ed n ew ed都必须是>删除 d,以使程序不会泄漏内存。另外,我们有智能内存管理

  • base base 缺少 Virtual destructor,当 delete ing ovjects时,它将导致不确定的行为。您应该为定义的行为添加一个。请参阅:何时使用虚拟破坏者?

使用 std :: simolor_ptr ,您的代码看起来像(示例代码):

#include <memory> // std::unique_ptr, std::make_unique

class Base
{
public:
    virtual void print() /* const */ = 0;
    // add a virtual destructor to the Base
    virtual ~Base() = default;
};

class Derived_1 : public Base
{
public:
    void print() override /* const */ {
        std::cout << "1" << std::endl;
    }
};

class Derived_2 : public Base
{
public:
    void print() override /* const */ {
        std::cout << "2" << std::endl;
    }
};

int main()
{
    std::vector<std::unique_ptr<Base>> v;
    v.reserve(2); // for unwanted re-allocations of memory
    v.emplace_back(std::make_unique<Derived_1>());
    v.emplace_back(std::make_unique<Derived_2>());

    for (const auto& i : v) // auto == std::unique_ptr<Base>
    {
        i->print();
    }
    return 0;
}

Coming from to , there are a lot to take-care; Especially memory management!

In your first shown case, you are slicing the objects. See What is object slicing?

In order to access the virtual functions, you should have used std::vector<Base*> (i.e. vector of pointer to Base), or std::vector<std::unique_ptr<Base>> or std::vector<std::shared_ptr<Base>>(i.e. vector of smart pointer to Base).

In your second shown code, your v is a vector of pointer to Base, meaning you need to access the members via the -> operator.

i.e. You should have accessed the print() as follows:

i->print();
^^^

Or alternatively:

(*i).print();
^^^^^

Also note that:

  • In your second case, whatever you newed must be deleted, so that the program doesn't leak memory. Alternately, we have smart memory management

  • The Base is missing a virtual destructor, which will lead to undefined behavior when deleteing the ovjects. You should add one for defined behavior. See: When to use virtual destructors?

Using std::unique_ptr, your code will look like (example code):

#include <memory> // std::unique_ptr, std::make_unique

class Base
{
public:
    virtual void print() /* const */ = 0;
    // add a virtual destructor to the Base
    virtual ~Base() = default;
};

class Derived_1 : public Base
{
public:
    void print() override /* const */ {
        std::cout << "1" << std::endl;
    }
};

class Derived_2 : public Base
{
public:
    void print() override /* const */ {
        std::cout << "2" << std::endl;
    }
};

int main()
{
    std::vector<std::unique_ptr<Base>> v;
    v.reserve(2); // for unwanted re-allocations of memory
    v.emplace_back(std::make_unique<Derived_1>());
    v.emplace_back(std::make_unique<Derived_2>());

    for (const auto& i : v) // auto == std::unique_ptr<Base>
    {
        i->print();
    }
    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文