且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

通过基类指针访问派生类的公共函数

更新时间:2023-02-14 23:24:13



我认为***的方法是让printTestObject本身为虚拟的
(基类的成员,并为每个

子类重写它。然后,对于圆形物体的被覆盖的版本,它将

已经知道它是一个圆圈,并且可以这样说然后获得并打印

半径没问题。同样,矩形'的覆盖版本将

输出矩形信息。这是使用派生对象的更好方法

比测试对象类型和根据类型调用函数更好。


至于你存储什么在数组中,你*应该*存储指针,

,因为你注意到,你可以毫无问题地存储基类指针。

然后,当你打电话例如,testArray [i] - > printTestObject(),

您将为您创建的特定实例获得正确的覆盖版本。这意味着您必须通过这些指针来管理

对象的创建和销毁,而不是使用初始化列表,但它是如何正确执行此操作的。

。 />

-Howard

I think the best approach would be to have the printTestObject itself be a
virtual (and abstract) member of the base class, and override it for each
sub-class. Then, for the circle object''s overridden version, it would
already know it''s a circle, and could say so and then get and print the
radius with no problem. Likewise, the rectangle''s overriden version would
output the rectangle info. That''s a much better way to use derived objects
than testing for the object type and calling functions based on the type.

As for what you store in the array, you *should* be storing pointers,
because, as you noticed, you can store base class pointers with no problem.
And then, when you call, for example, testArray[i]->printTestObject(),
you''ll get the correct overriden version for the specific instance you''ve
created. This means you have to manage the creation and destruction of the
objects via those pointers instead of using an initializer list, but it is
how to do this properly.

-Howard




" Banaticus Bart" < BA ******* @ yahoo.com>在消息中写道

新闻:1a ************************** @ posting.google.c om ...

"Banaticus Bart" <ba*******@yahoo.com> wrote in message
news:1a**************************@posting.google.c om...
我写了一个抽象基类,我从中派生了一些其他的类。我想创建一个基类数组,其中每个元素都是派生对象的一个​​实例。我可以创建一个指向派生类实例的基类指针,但当我将该基类指针传递给函数时,它无法访问派生的
对象公共职能。虽然,基类指针确实在派生类中调用了相应的虚函数。

这是代码的一部分,我已经在我的代码中发布了更多的注释
I wrote an abstract base class from which I''ve derived a few other
classes. I''d like to create a base class array where each element is
an instance of a derived object. I can create a base class pointer
which points to an instance of a derived class, but when I pass that
base class pointer into a function, it can''t access the derived
object''s public functions. Although, the base class pointer does call
the appropriate virtual function in the derived class.

Here''s a section of code, I''ve posted comments in my code to more
clearly communicate the problem I''m having.




我认为你需要阅读一本好的C ++书中的多态性。你的代码是

如此充满错误我不知道从哪里开始。事实上,我有点感到惊讶,你完全没有任何合理的行为。我不认为

它甚至应该编译。


这里有几个指针。


1)多态性与指针有关。您不创建基类

类对象的数组,您创建一个指向基类对象的指针数组。你好b / b
无法从对象获得多态行为,它必须是指针(或

引用)。


2)答案你真正的问题是你不需要。在你发布的代码中你应该创建一个名为print的虚函数,它打印出每个对象的详细信息

。然后你不需要访问派生类的公共方法

。如果您确实需要访问

派生类的公共方法,那么唯一的方法是使用static_cast将基类指针强制转换为

派生类指针或dynamic_cast。


希望这会有所帮助,

john



I think you need to read about polymorphism in a good C++ book. Your code is
so full of errors I don''t know where to start. In fact I''m somewhat
surprised you got any reasonable behaviour out of it at all. I don''t think
it should even compile.

Here''s a couple of pointers.

1) Polymorphism is all about pointers. You do not create an array of base
class objects, you create an array of pointers to base class objects. You
cannot get polymorphic behaviour from objects, it must be pointers (or
references).

2) The answer to your actual question is you don''t need to. In the code you
posted you should create a virtual function called print, which prints out
the details of each object. Then you don''t need to access the public methods
of derived classes. If you really do need to access the public methods of a
derived class, then the only way is to cast the base class pointer to a
derived class pointer using static_cast or dynamic_cast.

Hope this helps,
john


感谢您的帮助 - 我已经更改了测试器文件以使用数组

指针,但由于某种原因,变量名称被设置为每个对象的

空间。正在为每个

对象调用构造函数,因为calcArea仅在派生构造函数中调用,并且

正在打印正确的区域,但构造函数不会似乎正确地设置变量名称是
。 getName()返回 &QUOT; - 请参阅

printTestObject函数中的注释。我会发布

的基本形状代码和(派生的)圆形类作为对这个

帖子的回复。


#include< iostream>

#include" BAHshape.h"

#include" BAHcircle.h"

#包括BAHrectangle.h

#include" BAHcube.h"

int main()

{

void printTestObject(BAHshape *);


const int testArraySize = 3;

BAHshape * testArray [testArraySize] = {& BAHcircle (2.5,1,2),

& BAHrectangle(3.1,2,2,0,5),

& BAHcube(4,2,3,2) (b i = 0; i< testArraySize; i ++)

{

printTestObject(testArray [i]);

}

系统(暂停);

系统(" cls");

} //结束主函数


void printTestObject(BAHshape * testObject)

{

// getName return" &QUOT;出于某种原因

std :: string objectName = testObject-> getName();


//接下来的两行显示:" the area of这是:[area]"

//请注意,objectName是出于某种原因的空间

std :: cout<<"这个区域 ; << testObject-> getName()<<"是:&quot ;;

std :: cout<< testObject-> getArea()<< std :: endl;


/ /因为objectName是 ,跳过以下循环

if(objectName ==" circle")

{

BAHcircle * tempObject = dynamic_cast< BAHcircle *>(testObject);

std :: cout<<"这个圆圈的半径是:&quot ;;

std :: cout< < tempObject-> getRadius();

}


//这第二个如果块可能是其他的,如果,但我觉得

//为了更好的可读性而制作一个单独的块。

if(objectName ==" rectangle" || objectName ==" cube")

{

BAHrectangle * tempObject = dynamic_cast< BAHrectangle *>(testObject);

std :: cout<<"&quot ;;

std :: cout<< tempObject-> getName();

std :: cout<<"'的基数为;

std :: cout<< tempObject-> getBase();

std :: cout<<"它的高度是;

std :: cout<< tempObject-> getHeight();

if(objectName ==" cube")

{

BAHcube * tempObject = dynamic_cast< BAHcube *>(testObject);

std :: cout<<"它的深度是;

std :: cout<< tempObject-> getDepth();

}

std: :cout<<<"。\ n";

}


std :: cout<<""" << testObject-> getName()<<"位于(&;;

std :: cout<< testObject-> getXCoordinate()<<",";

std: :cout<< testObject-> getYCoordinate()<<",&quot ;;

std :: cout<< testObject-> getZCoordinate()<< ")。\ n&quot ;;

std :: cout<< std :: endl;

}
Thanks for your help -- I''ve changed the tester file to use an array
of pointers, but for some reason the variable name is getting set to a
space for every object. The constructor is being called for each
object, since calcArea is only called in the derived constructors, and
the correct area is being printed, but the constructor doesn''t seem to
be setting the variable name correctly. getName() returns " " -- see
the comments in the printTestObject function. I''ll post the code for
the basic shape and the (derived) circle classes as a reply to this
post.

#include <iostream>
#include "BAHshape.h"
#include "BAHcircle.h"
#include "BAHrectangle.h"
#include "BAHcube.h"

int main()
{
void printTestObject(BAHshape *);

const int testArraySize = 3;
BAHshape *testArray[testArraySize]={&BAHcircle(2.5, 1, 2),
&BAHrectangle(3.1, 2, 2, 0, 5),
&BAHcube(4, 2, 3, 2)};
for (int i = 0; i < testArraySize; i++)
{
printTestObject(testArray[i]);
}
system("pause");
system("cls");
} //end main function

void printTestObject(BAHshape *testObject)
{
//getName returns " " for some reason
std::string objectName = testObject->getName();

//the next two lines display: "The area of this is: [area]"
//note that objectName is a space for some reason
std::cout <<"The area of this " <<testObject->getName() <<" is: ";
std::cout <<testObject->getArea() <<std::endl;

//since objectName is " ", the following loop is skipped
if (objectName == "circle")
{
BAHcircle *tempObject = dynamic_cast<BAHcircle*>(testObject);
std::cout <<"This circle''s radius is: ";
std::cout <<tempObject->getRadius();
}

//this second if block could have been an else if, but I felt that
//a seperate if block made for better readability.
if (objectName == "rectangle" || objectName == "cube")
{
BAHrectangle *tempObject = dynamic_cast<BAHrectangle*>(testObject);
std::cout <<"The ";
std::cout <<tempObject->getName();
std::cout <<"''s base is ";
std::cout <<tempObject->getBase();
std::cout <<" and its height is ";
std::cout <<tempObject->getHeight();
if (objectName == "cube")
{
BAHcube *tempObject = dynamic_cast<BAHcube*>(testObject);
std::cout <<" and its depth is ";
std::cout <<tempObject->getDepth();
}
std::cout <<".\n";
}

std::cout <<"The " <<testObject->getName() <<" is located at (";
std::cout <<testObject->getXCoordinate() <<", ";
std::cout <<testObject->getYCoordinate() <<", ";
std::cout <<testObject->getZCoordinate() <<").\n";
std::cout <<std::endl;
}

>