“衍生的数组”不是一种“基数”阵列。题 [英] "array of Derived" is not a kind-of "array of Base" question

查看:50
本文介绍了“衍生的数组”不是一种“基数”阵列。题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

黑客攻击者,


我有一个继承自Node类的BuildNode类。


同样,我有一个继承的类BuildTree来自树类。


树包含一个成员变量:

vector< Node>节点; //为清楚起见,让它为orig_nodes


BuildTree包含一个成员变量:

vector< BuildNode>节点; //为了清楚起见,让它成为build_nodes


据我所知,这会重载节点,定义两个不同的

"节"变量而不是build_nodes clobber orig_nodes(因为

是我的意图)。


现在,让我们说我定义了一个Tree方法:

bool Tree :: is_degenerate const {return nodes.empty(); }


如果我有一个BuildTree对象build_tree,我调用

build_tree.is_degenerate(),它返回orig_nodes.empty(),不是
" build_nodes.empty()"按需要。


所以问题是:

有没有办法在Tree中定义引用节点的方法,并且

让那些方法对build_nodes进行操作如果调用对象是一个

BuildTree和orig_nodes如果调用对象是树,没有

复制BuildTree中的代码? [我想也许可以制作一个虚拟的

方法get_nodes(),它在Tree对象中返回orig_nodes,并在

a中,BuildTree对象返回build_nodes,然后每当我通常使用节点时调用get_nodes()

在树方法中。这个

有用吗?]


我不介意重构我的代码来做到这一点,如果有人可以

建议一个重新设计这些对象的好方法。


子问题:有两个节点在

BuildNodes对象中具有相同名称的对象是一种非常好的方式来拍摄自己的脚。

(我很惊讶代码工作了很久以前我今天早些时候发现了这个问题

。)有没有一个解决方案我可以完全取消这个

名称冲突?


Best,

JOSEPH

解决方案

Joseph Turian写道:

我有一个继承自Node类的BuildNode类。

同样,我有一个继承自Tree类的BuildTree类。

Tree包含一个成员变量:
矢量<节点>节点; //为了清楚起见,让它成为orig_nodes

BuildTree包含一个成员变量:
vector< BuildNode>节点; //为了清楚起见,让它成为build_nodes

据我所知,这会重载节点,定义两个不同的节点。变量而不是build_nodes clobber orig_nodes(因为
是我的意图)。


我不认为我听到过clobber这个词。与C ++构造有关。

Overload,override和hide等。成员们彼此做了什么。

现在,让我们说我定义了一个Tree方法:
bool Tree :: is_degenerate const {return nodes.empty(); }


bool Tree :: is_degenerate()const ...

如果我有一个BuildTree对象build_tree,我调用
build_tree.is_degenerate (),它返回orig_nodes.empty(),而不是
build_nodes.empty()如期望的那样。


正确...

所以问题是:
有没有办法在Tree中定义引用节点的方法,以及
让那些方法对build_nodes采取行动。如果调用对象是BuildTree和orig_nodes如果调用对象是树,没有在BuildTree中复制代码? [我在想可能会创建一个虚拟的方法get_nodes(),它在Tree对象中返回orig_nodes,并且在一个BuildTree对象中返回build_nodes,然后调用get_nodes()<无论什么时候我通常都会使用节点。在树方法中。这个
有用吗?]


是的,虚拟功能可行。但是,无论何时出现容器或

,我都会想到一个模板。所以,向你提出一个问题:为什么

不能让''树'成为模板?是的,你必须把''Node''模板设为



我不介意重构我的代码来做到这一点,如果任何人都可以建议一个重新设计这些对象的好方法。


他们是如何使用的?在不知情的情况下,如何建议一个体面的设计?

子问题:有两个节点在一个BuildNodes对象中具有相同名称的对象是一种非常好的方式来拍摄自己的脚。
(我很惊讶代码在我发现这个问题之前工作了很长时间
今天早些时候。)有没有一个解决方案,我可以完全取消这个名称冲突?




不确定你的意思。没有名字冲突。 BuildTree'''节点''

_hides_ Tree'''节点''。在BuildTree内部,基类''''节点'确实不存在
,基本上(除了占用一些空间)。


Victor


2005年1月18日10:38:19 -0800,Joseph Turian写道:

黑客攻击者,

同样,我有一个继承自Tree类的BuildTree类。

树包含一个成员变量:
vector<节点>节点; //为了清楚起见,让它成为orig_nodes

BuildTree包含一个成员变量:
vector< BuildNode>节点; //为了清楚起见,让它成为build_nodes

据我所知,这会重载节点,定义两个不同的节点。变量而不是build_nodes clobber orig_nodes(因为
是我的意图)。


有没有理由说基类不能有指针向量?

vector< Node *>节点;

允许你存储(指向)Node的对象或

BuildNode类型。当然,像

vector<升压:: shared_ptr的<节点> > ;;

使内存管理更容易。


或者,根据您的需要,使Tree成为模板类可能

工作对于你。

现在,让我们说我定义了一个Tree方法:
bool Tree :: is_degenerate const {return nodes.empty();如果我有一个BuildTree对象build_tree,我调用了
build_tree.is_degenerate(),它返回orig_nodes.empty(),而不是
build_nodes .empty()"如期望的那样。


根据

标准,这肯定听起来像是应该做的。

所以问题是:
有没有办法在Tree中定义引用nodes的方法,并且
让那些方法对build_nodes进行操作。如果调用对象是BuildTree和orig_nodes如果调用对象是树,没有在BuildTree中复制代码? [我在想可能会创建一个虚拟的方法get_nodes(),它在Tree对象中返回orig_nodes,并且在一个BuildTree对象中返回build_nodes,然后调用get_nodes()<无论什么时候我通常都会使用节点。在树方法中。这个
会起作用吗?]


有两种不同的方法可以让它与

两个单独的节点变量一起使用。当你(或其他人使用

代码)忘记使用变通方法时,所有这些都可能会导致你在某个地方出现问题。最好先将设计放在

的第一位,这样它就可以实现自然的设计。事情。

我不介意重构我的代码来做到这一点,如果有人能够建议一个重新设计这些对象的好方法。




如果不了解你想要解决的问题的更多信息,那么很难给出具体的建议。上面两个一般的想法之一

可能有用,但我可以很容易地想到这两种情况都不会有用。


-

Greg Schmidt gr***@trawna.com

Trawna出版物 http://www.trawna.com/




" Victor Bazarov" <五******** @ comAcast.net>在消息中写道

新闻:IU ******************* @ newsread1.mlpsca01.us.t o.verio.net ... < blockquote class =post_quotes> Joseph Turian写道:

我有一个继承自Node类的BuildNode类。

类似地,我有一个继承自Tree类的BuildTree类。

树包含一个成员变量:
vector< Node>节点; //为了清楚起见,让它成为orig_nodes

BuildTree包含一个成员变量:
vector< BuildNode>节点; //为了清楚起见,让它成为build_nodes

据我所知,这会重载节点,定义两个不同的节点。变量而不是build_nodes clobber orig_nodes(因为
是我的意图)。



我不认为我听到过clobber这个词。与C ++构造有关。
Overload,override和hide等。成员们彼此做了什么。




我已经看过(并被逗乐了)它与C一起使用:数据库手册

库,在几个函数的描述中警告:确保你

分配足够的缓冲区空间,否则内存将被破坏。

我可能会有它说''覆盖'',但是,嘿,我得到了消息的b / b
。这可能是唯一存在的软件相关文件

几十次使用clobber一词。 :-)


-Mike


Fellow hackers,

I have a class BuildNode that inherits from class Node.

Similarly, I have a class BuildTree that inherits from class Tree.

Tree includes a member variable:
vector<Node> nodes; // For clarity, let this be "orig_nodes"

BuildTree includes a member variable:
vector<BuildNode> nodes; // For clarity, let this be "build_nodes"

So as far as I can tell, this overloads "nodes", defining two different
"nodes" variables instead of having build_nodes clobber orig_nodes (as
was my intention).

Now, let''s say I have a Tree method defined:
bool Tree::is_degenerate const { return nodes.empty(); }

If I have a BuildTree object build_tree, and I call
build_tree.is_degenerate(), it returns "orig_nodes.empty()", not
"build_nodes.empty()" as is desired.

So the question is:
Is there any way to define methods in Tree that reference "nodes", and
get those methods to act upon "build_nodes" if the calling object is a
BuildTree and "orig_nodes" if the calling object is a Tree, without
duplicating the code in BuildTree? [I was thinking maybe make a virtual
method "get_nodes()", which in a Tree object returns orig_nodes and in
a BuildTree object returns "build_nodes", and then call get_nodes()
whenever I would normally use "nodes" in Tree methods. Would this
work?]

I don''t mind refactoring my code to get this right, if anyone can
suggest a good way to redesign these objects.

Sub-question: Having two "nodes" objects with the same name in a
BuildNodes object is a really good way to shoot oneself in the foot.
(I''m surprised the code worked for so long before I found this issue
earlier today.) Is there a solution in which I can do away with this
name clash entirely?

Best,
JOSEPH

解决方案

Joseph Turian wrote:

I have a class BuildNode that inherits from class Node.

Similarly, I have a class BuildTree that inherits from class Tree.

Tree includes a member variable:
vector<Node> nodes; // For clarity, let this be "orig_nodes"

BuildTree includes a member variable:
vector<BuildNode> nodes; // For clarity, let this be "build_nodes"

So as far as I can tell, this overloads "nodes", defining two different
"nodes" variables instead of having build_nodes clobber orig_nodes (as
was my intention).
I don''t think I heard the term "clobber" in relation to C++ constructs.
"Overload", "override", and "hide" is what members do to each other.
Now, let''s say I have a Tree method defined:
bool Tree::is_degenerate const { return nodes.empty(); }
bool Tree::is_degenerate() const ...
If I have a BuildTree object build_tree, and I call
build_tree.is_degenerate(), it returns "orig_nodes.empty()", not
"build_nodes.empty()" as is desired.
Right...
So the question is:
Is there any way to define methods in Tree that reference "nodes", and
get those methods to act upon "build_nodes" if the calling object is a
BuildTree and "orig_nodes" if the calling object is a Tree, without
duplicating the code in BuildTree? [I was thinking maybe make a virtual
method "get_nodes()", which in a Tree object returns orig_nodes and in
a BuildTree object returns "build_nodes", and then call get_nodes()
whenever I would normally use "nodes" in Tree methods. Would this
work?]
Yes, a virtual function would work. However, any time a container or the
like comes up, a template comes to my mind. So, a question to you: why
not make ''Tree'' a template? Yes, you''d have to make ''Node'' a template as
well.
I don''t mind refactoring my code to get this right, if anyone can
suggest a good way to redesign these objects.
How are they used? Without knowing that, how can one suggest a decent
design?
Sub-question: Having two "nodes" objects with the same name in a
BuildNodes object is a really good way to shoot oneself in the foot.
(I''m surprised the code worked for so long before I found this issue
earlier today.) Is there a solution in which I can do away with this
name clash entirely?



Not sure what you mean. There is no name clash. BuildTree''s ''nodes''
_hides_ Tree''s ''nodes''. Inside BuildTree the base class'' ''nodes'' does
not exist, essentially (except that it takes up some space).

Victor


On 18 Jan 2005 10:38:19 -0800, Joseph Turian wrote:

Fellow hackers,

I have a class BuildNode that inherits from class Node.

Similarly, I have a class BuildTree that inherits from class Tree.

Tree includes a member variable:
vector<Node> nodes; // For clarity, let this be "orig_nodes"

BuildTree includes a member variable:
vector<BuildNode> nodes; // For clarity, let this be "build_nodes"

So as far as I can tell, this overloads "nodes", defining two different
"nodes" variables instead of having build_nodes clobber orig_nodes (as
was my intention).
Is there a reason why the base class can''t have a vector of pointers?
vector<Node*> nodes;
would allow you to store (pointers to) objects of either Node or
BuildNode type. Of course, something like
vector< boost::shared_ptr<Node> >;
makes memory management easier.

Alternately, depending on your needs, making Tree a template class might
work for you.
Now, let''s say I have a Tree method defined:
bool Tree::is_degenerate const { return nodes.empty(); }

If I have a BuildTree object build_tree, and I call
build_tree.is_degenerate(), it returns "orig_nodes.empty()", not
"build_nodes.empty()" as is desired.
That certainly sounds like it''s doing what it should, according to the
standard.
So the question is:
Is there any way to define methods in Tree that reference "nodes", and
get those methods to act upon "build_nodes" if the calling object is a
BuildTree and "orig_nodes" if the calling object is a Tree, without
duplicating the code in BuildTree? [I was thinking maybe make a virtual
method "get_nodes()", which in a Tree object returns orig_nodes and in
a BuildTree object returns "build_nodes", and then call get_nodes()
whenever I would normally use "nodes" in Tree methods. Would this
work?]
There are probably lots of hackish ways of getting this to work with the
two separate nodes variables. All of them are likely to cause you a
problem somewhere down the line when you (or someone else working on the
code) forget to use the workaround. Best to get the design right in the
first place, so that it does the "natural" thing.
I don''t mind refactoring my code to get this right, if anyone can
suggest a good way to redesign these objects.



Without knowing more about the problem you''re trying to solve, it''s very
hard to give concrete suggestions. One of the two general ideas above
might work, but I can easily think of cases where neither would be
useful.

--
Greg Schmidt gr***@trawna.com
Trawna Publications http://www.trawna.com/



"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:IU*******************@newsread1.mlpsca01.us.t o.verio.net...

Joseph Turian wrote:

I have a class BuildNode that inherits from class Node.

Similarly, I have a class BuildTree that inherits from class Tree.

Tree includes a member variable:
vector<Node> nodes; // For clarity, let this be "orig_nodes"

BuildTree includes a member variable:
vector<BuildNode> nodes; // For clarity, let this be "build_nodes"

So as far as I can tell, this overloads "nodes", defining two different
"nodes" variables instead of having build_nodes clobber orig_nodes (as
was my intention).



I don''t think I heard the term "clobber" in relation to C++ constructs.
"Overload", "override", and "hide" is what members do to each other.



I''ve seen (and been amused by) it used with C: The manual for a database
library, in descriptions of several functions warned: "Be sure you
allocate sufficient buffer space, or memory will be clobbered".
I would have probably had it say ''overwritten'', but hey, I got
the message. That was probably the only software-related document
in existence that used the term ''clobber'' dozens of times. :-)

-Mike


这篇关于“衍生的数组”不是一种“基数”阵列。题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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