C ++如何显示类Vector中的不同类型的参数?

Posted

技术标签:

【中文标题】C ++如何显示类Vector中的不同类型的参数?【英文标题】:C++ How to get display different types of parameters that is in a class Vector? 【发布时间】:2018-08-21 07:59:23 【问题描述】:

我是学习 C++ 的新手,现在特别学习多态性和继承,所以请原谅我的以下问题,我不确定这是否可能?如果不是,请建议我应该怎么做。

我有一个存储以下内容的父类:

ShapeTwo (string, bool, int, int)

我有两个派生自父类的类(Square 和 Rectangle)。我已经设法将我的子类推到这个向量中: vector<ShapeTwo*> objs;

objs.push_back(new Square(square));
objs.push_back(new Rectangle(rectangle));

所以现在我的 objs.size() = 2,因为现在有 2 个 ShapeTwo。

现在我一直在研究如何循环它,以便打印出存储在类向量中每个元素中的每个单独的类型。程序可以编译运行,但结果不是预期的。

//loop to print out each shape details
for(int i = 0; i < objs.size(); i++)

    cout << "Shape no. :" << objs.at(i) << endl;
    cout << "Name :" << objs[i] -> getName() << endl;
    cout << "Bool type :" << objs[i] -> getWarpSpace() << endl;
    cout << endl;


//results
Shape no. :0x9363a60
Name :
Bool type :

Shape no. :0x9363ae0
Name :
Bool type :

当我试图打印出向量的位置时,它会打印出一些奇怪的字符。我试图获得的其他价值不是打印出来的。如何检查我的向量是否存储了正确的值?

请帮忙。

已编辑以包含声明

ShapeTwo.h
class ShapeTwo

protected:
    string name, specialType;
    bool containsWarpSpace;

public:
    ShapeTwo();
    ShapeTwo(string, bool);

    string getName();
    void setName(string);
    void setWarpSpace(string);
    string getWarpSpace();
;

class Square:public ShapeTwo

public:
    Square();
    Square(string, bool, int, int);
;

class Rectangle:public ShapeTwo

public:
    Rectangle();
    Rectangle(string, bool, int, int);
;

编辑以包含定义

void ShapeTwo::setName(string name)

    this -> name = name;


string ShapeTwo::getName()

    return (name);

【问题讨论】:

包括你的基本形状类的声明以及你的矩形和正方形类,看看你发布的内容,我发现了一些主要的设计缺陷。 @vividpk21 我已经包含了声明!你觉得有什么缺陷? 我在回答中列出了我能想到的所有内容,您投反对票的原因是因为您似乎不知道自己在做什么。我实际上正在努力学习这是完全可以接受的,但你需要先学习基础知识。 当你想要多态性时,你通常不关心对象的实际类型是什么,但你只能通过它们的公共接口(即基类的接口)访问它们。如果不是这样,那你为什么首先要多态呢? 请附上minimal reproducible example。很难理解您的代码片段 【参考方案1】:

我猜实际的问题如下:

如何检查我的向量是否存储了正确的值?

    使用 IDE: 除非您使用简单的文本编辑器编写代码并从命令提示符编译,否则您可能使用的是集成开发环境 (IDE)。大多数 IDE 都带有调试工具,您将从学习中受益匪浅。其中通常是一种告诉程序在遇到特定代码行时暂停的方法。当程序暂停时,通常有一种方法可以检查变量的值。一旦您知道如何使用这些工具,它们将帮助您调试程序比在这里询问要快得多。

    自我记录:如果您没有使用 IDE,您可能会发现在对象中编写一个将其内容写入流的方法很有用。然后你可以从像cout &lt;&lt; *objs[i]; 这样的语句中获得有用的调试输出(注意星号,因为你想要objs[i] 指向的对象,而不是指针本身)。这种方法的一个优点是您的日志记录可以更准确,而无需周围的代码对存在哪些(派生)对象进行假设。稍后我将举例说明如何执行此操作,因此不会过多干扰此列表。

    临时日志记录:为了快速检查代码的完整性,您可以执行您正在执行的操作:将对象中的各种数据位写入输出流。这样做的一个很大的缺点是,如果对象的数据与您认为的大不相同,您可能会对输出感到完全困惑。 [说到这个,我想你完全被输出搞糊涂了。我在您尝试记录信息时看到的唯一完全错误是数组中的位置(形状编号)是循环的控制变量(i),而不是指针 at 该位置(@987654325 @)。指针往往以十六进制形式打印,如 0x9363a60,而确切的值往往无法提供信息(某些特殊情况除外)。]

总之,我认为您确实检查了向量中的值,发现这些值不是您想要的。您的对象的名称和扭曲空间似乎是空字符串,但您期望它们中有一些内容。您的下一步可能是通过转到选项 1 或 2 来升级您的调试游戏。


那么如何实现自我记录呢?我会首先推荐一个IDE。但是,有时有人可能会找到这个答案,并且由于某种原因无法使用 IDE。所以我会举一个例子。请理解后面的代码 sn-ps 可能包含错误——它们只是为了给你指明正确的方向。另请理解,这只是可以采取的几种方法中的一种。

我将使用问题中的设置。有一个基类ShapeTwo 和派生类SquareRectangle。首先,我可能会声明基类的朋友来处理所需的接口 (operator&lt;&lt;)。添加pure virtual function 来处理实际的流式传输:

class ShapeTwo

    // Existing declaration goes here
private:
    friend std::ostream& operator<<(std::ostream&, const ShapeTwo&);
    virtual std::ostream& to_stream(std::ostream&) = 0;
;

然后我将覆盖最派生类中的纯虚函数。例如,Rectangle 类中的版本可能如下所示。 (当然细节可能会有所不同,具体取决于您存储矩形的方式。)

std::ostream& Rectangle::to_stream(std::ostream& os)

    return os << "rectangle from " << x1 << ',' << y1 << " to " << x2 << ',' << y2;

这里的想法是让记录每个类的正确操作变得容易。您有成员函数的便利,如果您忘记为任何实例化类定义它,编译器会警告您。您只需要在基类中处理 friend 即可。说到朋友,这个函数需要在某个地方定义。它可能如下所示。

std::ostream& operator<<(std::ostream& os, const ShapeTwo& obj)

    return obj.to_stream(os);

这就是它的要点。如果您不能使用 IDE 进行调试,您可能会发现能够流式传输对象很有用,而不必担心在尝试调试其他内容时要流式传输哪些细节。以上提供了一种方法。

【讨论】:

【参考方案2】:

让我们看看:

cout << "Name :" << objs[i] -> getName() << endl;
cout << "Bool type :" << objs[i] -> getWarpSpace() << endl;

如果上面的打印结果确实给你空白值,这意味着你没有在你的类中设置变量,或者你已经创建了一个 void 返回函数,所以在这里了解函数:Difference between void and non-void functions in C++

objs.push_back(new Square(square));
objs.push_back(new Rectangle(rectangle));

老实说,我不知道这些在做什么,但您似乎需要学习如何声明构造函数,可以在这里找到:Different ways of using C++ constructors 和这里:C++ Constructor 这也将有助于您拥有的变量没有设置。

因为当我尝试使用以下代码显示向量值时: cout

因此显示的数字称为指针,您可以在此处找到有关它的更多信息:https://www.learncpp.com/cpp-tutorial/6-8a-pointer-arithmetic-and-array-indexing/,其中还包含您需要学习的数组索引。

【讨论】:

是的,这是家庭作业。我认为这可能是寻求帮助的最佳网站,因为我只是一名学习学生。感谢您的帮助!我已经阅读了关于 void 返回函数的内容,但是我上面调用的函数不是 void?我的getName() is stringgetWarpSpace() is string 我会努力研究和学习更多。感谢您的帮助。 没问题,我知道人们会如何看待我所说的话,但我想提供帮助。

以上是关于C ++如何显示类Vector中的不同类型的参数?的主要内容,如果未能解决你的问题,请参考以下文章

类 C 语言中的返回类型多态性

单个 fetchedResultsController 中的不同实体类型?

基于第二个参数的不同值的计数

如何在Java中修复“类Rectangle中的构造函数不能应用于给定类型”错误?

如何使用c#中的不同值更新数据库中的多行?

如何将不同类型的结构体作为一个函数的参数?