覆盖子类中的虚拟成员函数 [英] Override virtual member functions in Subclasses

查看:64
本文介绍了覆盖子类中的虚拟成员函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我在派生类中使用成员函数时遇到问题

覆盖基类的虚拟成员函数。


以下(简化)代码片段不起作用。任何人都可以给我一些关于可能出错的提示吗?


//开始样品代码

class Strategy

{

public:

策略(){}

virtual void run(){cout<<"请覆盖!" ;; }

};


类策略A:公共策略

{

public:

策略A(){}

void run();

};

void StategyA :: run()

{

cout<<""功能A" ;;

}

class SomeClass

{

public:

SomeClass(策略版);


void doSomething();


私人:

策略s_;

};


SomeClass :: SomeClass(策略版) :s_(s){}


SomeClass :: doSomething()

{

s_.run();

}

int main()

{

StategyA s;

SomeClass c( s);


c.doSomething();


返回0;

}

//示例代码结束

上述程序将打印出请覆盖!而不是

功能A。通过Stroustrup扫描我似乎无法找到

出了什么问题。


另外一句话:我知道声明函数更好/>
" run"在策略中是纯虚拟的(virtual void run()= 0;)但是

不能编译。编译器在SomeClass的构造函数

和私有成员声明中给出错误。我忘记了什么?


在此先感谢,


亲切的问候


Ruben Van Havermaet。

解决方案

" Ruben Van Havermaet" < RV ****** @ yahoo.co.uk>在消息中写道

新闻:54 ************************** @ posting.google.c om ...



我在派生类中使用成员函数时遇到问题,这些函数覆盖了基类的虚拟成员函数。

以下(简化)代码片段不起作用。谁能给我一些关于可能出错的提示?

//开始样品代码


你知道吗,但我''我要继续把它放在这里:


#include< iostream>

使用std :: cout;

课程策略
{
公开:
策略(){}
virtual void run(){cout<<" Please override!" ;; }
};

类策略A:公共策略
公开:
策略A(){}
void run();


样式:上面的run()函数是虚拟的;最好继续说

" virtual"提醒你它是什么。

};
void StategyA :: run()


void StrategyA :: run()

{
cout<<""功能A" ;;
}

class SomeClass
{
public:
SomeClass(策略版);


样式:无论你做什么,构造函数和析构函数都是内联的,所以

通常最好将构造函数/析构函数定义放在

这样的类:


SomeClass(策略版):s_(s){}


此外,初始化这样的数据成员没有任何效果。私人

成员变量策略s_已经是一个策略。 "初始化"它有一个

策略A没有效果。没有需要初始化的数据,并且无论如何都不能用另一个对象初始化对象。


将构造函数更改为:


SomeClass(){}

void doSomething();

私人:
策略s_;


SomeClass的'数据成员是战略,而不是战略A.如果你改变了这个




策略A s_;


那么它会起作用。

};

SomeClass :: SomeClass(策略版):s_(s){}


删除上面的行。

SomeClass :: doSomething()


void SomeClass :: doSomething()


如果你不提供退货类型,假设为int。由于此功能

不返回值,因此无效。

{
s_.run();
}

int main()
{
StategyA s;


这应该是


策略A;


除了它不应该是那里。

SomeClass c(s);


更改为


SomeClass c;


完成所有这些更改后,程序应该工作。

c.doSomething();


这将打印功能A。现在。

返回0;
}
//示例代码结束

上述程序将打印出请覆盖!而不是功能A。扫描Stroustrup我似乎无法找到
出了什么问题。

另外一句话:我知道最好宣布一个功能
run在策略中是纯虚拟的(virtual void run()= 0;)但是
不会编译。编译器在SomeClass的构造函数
和私有成员声明中给出错误。我忘记了什么?




声明一个纯虚函数使该类成为ADT(抽象数据

类型)。因为你不能创建ADT的对象,所以它必须有一个

默认构造函数(但那已经存在)。问题来自

试图给SomeClass一个策略成员。当你这样做时,一个策略

对象被构造了。在SomeClass里面,这是一个错误。 SomeClass

构造函数错误基本相同;它来自于尝试初始化

策略ADT的一个对象。


这是我的代码版本。应该让一切正常。


#include< iostream>


使用std :: cout;


class策略


{


public:


策略(){}


virtual void run(){cout<<" Please override!" ;; }


};


类策略A:公共策略


{


public:


策略A(){}


虚拟空运行();


};


无效策略A ::运行()


{


cout<<"功能A \ n" ;;


}


class SomeClass

{


public:


SomeClass(){}


void doSomething();


私人:


策略A s_;


};


void SomeClass :: doSomething()


{


s_.run();


}


int main()


{


SomeClass c;


c.doSomething();


返回0;


}


//祝你好运!


// mike tyndall


Stephen Tyndall发布:
< blockquote class =post_quotes>如果您不提供返回类型,则假定为int。由于此函数没有返回值,因此需要void。



不正确。


有三个且只有三个实例你可能没有指定

返回类型(并且在所有三种情况下都是强制性的,你不能):


a)构造函数


b)析构函数


c)类型转换运算符

class Blah

{

public:


Blah();


~Blah();


operator int();

};

-JKop


Stephen Tyndall写道:

Ruben Van Havermaet < RV ****** @ yahoo.co.uk>在消息中写道
新闻:54 ************************** @ posting.google.c om ...

类SomeClass
{
公开:
SomeClass(策略版);

样式:无论你做什么,构造函数和析构函数都是内联的,所以




你在哪里得到这个废话?

通常最好将构造函数/析构函数定义放在
中像这样的类:

SomeClass(策略s):s_(s){}

此外,初始化像这样的数据成员没有任何效果。


你在说什么?

私人
成员变量策略s_已经是一个策略。 "初始化"它与
StrategyA无效。


你不在乎吗?

没有需要初始化的数据,而且


如果我以后添加要初始化的数据怎么办?

无论如何你都不能用另一个对象初始化一个对象。


什么????

将构造函数更改为:
[...]



我删除了剩余的废话。在尝试告知毫无戒心的新手之前,请先阅读多态性




V


Hi,

I have a problem using member functions in derived classes that
override virtual member functions of base classes.

The following pieces of (simplified) code don''t work. Can anybody give
me some hints on what might be wrong?

// BEGIN OF SAMPLE CODE
class Strategy
{
public:
Strategy() {}
virtual void run() { cout<<"Please override!"; }
};

class StrategyA: public Strategy
{
public:
StrategyA() {}
void run();
};
void StategyA::run()
{
cout <<"Functionality A";
}
class SomeClass
{
public:
SomeClass(Strategy s);

void doSomething();

private:
Strategy s_;
};

SomeClass::SomeClass(Strategy s): s_(s) {}

SomeClass::doSomething()
{
s_.run();
}
int main()
{
StategyA s;
SomeClass c(s);

c.doSomething();

return 0;
}
// END OF SAMPLE CODE
The above program will print out "Please override!" instead of
"Functionality A". Scanning through Stroustrup I can''t seem to find
what is wrong.

An additional remark: I know it is better to declare the function
"run" in Strategy to be pure virtual (virtual void run() = 0;) but
that won''t compile. The compiler gives error in SomeClass'' constructor
and private member declaration. What do I forget?

Thanks In Advance,

With Kind Regards

Ruben Van Havermaet.

解决方案

"Ruben Van Havermaet" <rv******@yahoo.co.uk> wrote in message
news:54**************************@posting.google.c om...

Hi,

I have a problem using member functions in derived classes that
override virtual member functions of base classes.

The following pieces of (simplified) code don''t work. Can anybody give
me some hints on what might be wrong?

// BEGIN OF SAMPLE CODE
You know this, but I''m going to go ahead and put it here:

#include <iostream>
using std::cout;
class Strategy
{
public:
Strategy() {}
virtual void run() { cout<<"Please override!"; }
};

class StrategyA: public Strategy
{
public:
StrategyA() {}
void run();
Style: the run() function above is virtual; it''s best to go ahead and say
"virtual" to remind you what it is.
};
void StategyA::run()
void StrategyA::run()
{
cout <<"Functionality A";
}
class SomeClass
{
public:
SomeClass(Strategy s);
Style: constructors and destructors are inline no matter what you do, so
it''s usually best just to put the constructor/destructor definitions inside
the class like this:

SomeClass(Strategy s) : s_(s) { }

Also, initializing a data member like this has no effect. The private
member variable Strategy s_ is already a Strategy. "Initializing" it with a
StrategyA has no effect. There is no data that needs to be initialized, and
you can''t initialize a object with another object anyway.

Change your constructor to:

SomeClass() { }

void doSomething();

private:
Strategy s_;
SomeClass'' data member is a Strategy, not a StrategyA. If you changed this
to

StrategyA s_;

Then it will work.
};

SomeClass::SomeClass(Strategy s): s_(s) {}
Erase the line above.

SomeClass::doSomething()
void SomeClass::doSomething()

If you don''t supply a return type, int is assumed. Since this function
returns no value, void is required.
{
s_.run();
}
int main()
{
StategyA s;
This should be

StrategyA s;

except that it shouldn''t be there.
SomeClass c(s);
Change this to

SomeClass c;

After all these changes, the program should work.

c.doSomething();
This will print "Functionality A" now.

return 0;
}
// END OF SAMPLE CODE
The above program will print out "Please override!" instead of
"Functionality A". Scanning through Stroustrup I can''t seem to find
what is wrong.

An additional remark: I know it is better to declare the function
"run" in Strategy to be pure virtual (virtual void run() = 0;) but
that won''t compile. The compiler gives error in SomeClass'' constructor
and private member declaration. What do I forget?



Declaring a pure virtual function makes the class an ADT (abstract data
type). Because you cannot create an object of an ADT, it must have a
default constructor (but that''s already there). The problem comes from
trying to give SomeClass a Strategy member. When you do this, a Strategy
object is "constructed" inside SomeClass, which is an error. The SomeClass
constructor error is basically the same; it comes from trying to initialize
an object of the Strategy ADT.

Here''s my version of your code. It should have everything working.

#include <iostream>

using std::cout;

class Strategy

{

public:

Strategy() {}

virtual void run() { cout<<"Please override!"; }

};

class StrategyA: public Strategy

{

public:

StrategyA() {}

virtual void run();

};

void StrategyA::run()

{

cout <<"Functionality A\n";

}

class SomeClass

{

public:

SomeClass() { }

void doSomething();

private:

StrategyA s_;

};

void SomeClass::doSomething()

{

s_.run();

}

int main()

{

SomeClass c;

c.doSomething();

return 0;

}

//good luck!

//mike tyndall


Stephen Tyndall posted:

If you don''t supply a return type, int is assumed. Since this function
returns no value, void is required.


Incorrect.

There are three and only three instances in which you may not specify a
return type (and in all three instances it is compulsory that you don''t):

a) Constructors

b) Destructor

c) Type conversion operators
class Blah
{
public:

Blah();

~Blah();

operator int();
};
-JKop


Stephen Tyndall wrote:

"Ruben Van Havermaet" <rv******@yahoo.co.uk> wrote in message
news:54**************************@posting.google.c om...

class SomeClass
{
public:
SomeClass(Strategy s);

Style: constructors and destructors are inline no matter what you do, so



Where did you get this nonsense?
it''s usually best just to put the constructor/destructor definitions inside
the class like this:

SomeClass(Strategy s) : s_(s) { }

Also, initializing a data member like this has no effect.
What are you talking about?
The private
member variable Strategy s_ is already a Strategy. "Initializing" it with a
StrategyA has no effect.
Are you out of your mind?
There is no data that needs to be initialized, and
What if I later add data to be initialised?
you can''t initialize a object with another object anyway.
What????

Change your constructor to:
[...]



I removed the rest of your nonsense. Please read up on polymorphism
before attempting to advise unsuspecting newbies.

V


这篇关于覆盖子类中的虚拟成员函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆