组合关系/前向参考问题。 [英] Problem with Composition Relation/Forward Referencing.

查看:45
本文介绍了组合关系/前向参考问题。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述




我试图实现一个组合关系,类似于

以下类型:


class A

{

public:

class B

{

int member_of_B;

};


B b;

// ...其他一些成员;

};

但由于B的定义太大我以为可能会把它写成

外面。 )。所以我修改了课程:

A级

{

B级;

B b;

....

};


B级{

int member_of_B;

};


我们这里有两个问题:


1.包括.h在内的任何人(我已经宣布了这些课程)

将获得B类并可以使用它。我并不打算允许;)。


2. gcc 3.3.2给了我这种类型的错误:


错误:字段b具有不完整类型


我是否不允许使用正向引用?

声明究竟是什么


B类;


的定义是什么?它不会在A中引入类型名吗?


有什么建议吗?我错过了一些明显的东西吗?


~M。

解决方案

Milind写道:< blockquote class =post_quotes>

我试图实现一个组合关系,以下类型的东西:

A类
{
公开:
B级
{
int member_of_B;
};

B b;
// ..其他一些成员;
};

但由于B的定义太大,我想到可能会在外面写它。 )。所以我修改了课程:

A级
{B / B级;
B b;
...
}; < B组{
int member_of_B;
};

我们这里有两个问题:

1.任何人包括 ; .h (我已经宣布了这些类)
将得到类型B并且可以使用它。我并不打算允许;)。

2. gcc 3.3.2给了我这种类型的错误:

错误:字段`b''有不完整的类型

我不允许使用前向引用?


B类究竟是什么;在A的定义中做什么?它不是在A中引入了typename吗?


这里有几个误解。前往

声明的正确方法是


B级;


A级

{

B b;

};


B级

{

};


由于B类是在A类之外宣布的,因此前向声明

也必须在A类之外。


但第二个误解是,一个不完整的课程(在前瞻性申报和实际申报之间是B的B $ B $

仅适用于极少数事情,例如声明指针。在你的
代码中,编译器需要知道B的大小才能为A生成代码

,但它不知道B的大小只是来自前向声明。


显而易见的解决办法就是颠倒你定义班级的顺序。


另一种解决方案是重写A这样的


B级;


A级

{

B * b;

};


通过使用指针,您不需要在
根据头文件。这也可能有助于您的其他要求

B本身无法使用。

有什么建议吗?我错过了一些明显的东西吗?




不明显,但我猜你是来自Java背景并且没有

相当吸收,但C ++中的对象是值而不是引用。轻松

Java和C ++之间最基本的区别。


john


>前进

声明的正确方法是B类;

A类
{b / b;
};

B班
{
};


好​​吧即使这样也不会工作;(我复制粘贴上面的内容并尝试使用g ++ 3.3.2在我的Debian盒子上编译它。) />

除此之外,

由于B级是在A级之外宣布的,因此前方声明
也必须在A级之外。


根据我以前的帖子...

1.任何人包括.h......我并不打算允许;。


我不希望任何人直接使用B级,我总是希望其他人使用

它作为A :: B,即作为A类的一部分。以你建议的方式宣布
建议将允许其他人按原样使用它。


使它成为一个成员肯定会强制使用B类对象。但是,我们不能使用裸B类物品来停止使用



然而第二个误解是一个不完整的类(这是
B在前向声明和实际声明之间是什么)只对很少的东西有用,例如声明指针。


是的;指针工作,因为他们有相同的大小,我们不分配内存。

我尝试b4发布在这里,并且它工作正常。这就是为什么我对b
对前向引用感到困惑的原因。如果类型已知,为什么不能
编译器再做一次分配mem?

编译器需要知道B的大小才能为A生成代码,但它不知道前向声明中B的大小。


这就是为什么我问:我不允许使用前向参考?


B类究竟是什么;在A的定义中做什么?它不是在A中引入了typename吗?

i意味着编译器不会再做第二遍以获得大小和

的东西吗?

显而易见的解决方案就是颠倒你定义类的顺序。


嗯......但是如果我在A级之外定义B级,我会得到它

暴露给任何人,包括头文件。
A类
{B / B;
};

通过使用指针,您根本不需要在头文件中包含B的定义。这也可能有助于你的其他要求
B本身不可用。


我不知道如何通过在类中声明指针我可以限制

B'的用法。请问你好吗?


我尝试用私人构造函数和朋友实现这个功能

函数。然而,必要的是在语义上意味着其他东西。

我想实现像 - >这样的东西。 A :: B总是。

有什么建议吗?我错过了一些明显的东西吗?



不明显




Thnx。因为我很担心:)

john




Thnx。

~M


可能''pimpl''成语可以帮助你:

http://www.gotw.ca/publications/mill04.htm


再见

Fabio


Hi,

I was trying to implement a composition relation, somthing of the
following type:

class A
{
public:
class B
{
int member_of_B;
};

B b;
// ... some other members;
};
but as the defintion of B is too large I thought of may be writing it
outside. ;). So i modified the class as:
class A
{
class B;
B b;
....
};

class B {
int member_of_B;
};

We have two issues here:

1. anybody including "the .h" (in which i have declared the classes)
would get the type B and can use it. which i didn''t intend to allow ;).

2. gcc 3.3.2 gave me an error of this type:

error: field `b'' has incomplete type

Am I not allowed to use forward referencing ? What exactly does the
statement

class B;

in definition of A do? Doesn''t it introduce the typename in A?

Any suggestions? Am I missing something obvious ?

~ M.

解决方案

Milind wrote:

Hi,

I was trying to implement a composition relation, somthing of the
following type:

class A
{
public:
class B
{
int member_of_B;
};

B b;
// ... some other members;
};
but as the defintion of B is too large I thought of may be writing it
outside. ;). So i modified the class as:
class A
{
class B;
B b;
...
};

class B {
int member_of_B;
};

We have two issues here:

1. anybody including "the .h" (in which i have declared the classes)
would get the type B and can use it. which i didn''t intend to allow ;).

2. gcc 3.3.2 gave me an error of this type:

error: field `b'' has incomplete type

Am I not allowed to use forward referencing ? What exactly does the
statement

class B;

in definition of A do? Doesn''t it introduce the typename in A?
A couple of misunderstandings here. The correct way to make the forward
declaration is

class B;

class A
{
B b;
};

class B
{
};

Since class B is declared outside of class A, the forward declaration
must also be outside of class A.

But the second misunderstanding is that an incomplete class (which is
what B is between the forward declaration and the actual declaration) is
only good for a very few things, for instance declaring pointers. In you
code the compiler needs to know the size of B in order to generate code
for A, but it does not know the size of B from just the forward declaration.

The obvious solution to this is just to reverse the order in which you
define your classes.

The other solution would be to rewrite A like this

class B;

class A
{
B* b;
};

By using a pointer you would not need to include the definition of B in
the header file at all. This might also help with your other requirement
that B not be usable by itself.

Any suggestions? Am I missing something obvious ?



Not obvious, but I''d guess you come from a Java background and haven''t
quite absorbed yet that objects in C++ are values not references. Easily
the most fundamental difference between Java and C++.

john


> The correct way to make the forward

declaration is

class B;

class A
{
B b;
};

class B
{
};
Well Even that wont work ;( i copy pasted the above stuff and tried to
compile it with g++ 3.3.2 on my Debian box.

That thing apart,
Since class B is declared outside of class A, the forward declaration
must also be outside of class A.
As per my previous posting...

1. anybody including "the .h" .... "which i didn''t intend to allow" ;).
I dont want anybody use class B directly, i always want others to use
it as A::B ,i.e as a part of class A. declaring in the way you
suggested will allow everyone else to use it as is.

making it a member would definitely impose using object of class B
inside A''s object with this syntax. however, we can''t stop ppl from
using bare class B objects.


But the second misunderstanding is that an incomplete class (which is
what B is between the forward declaration and the actual declaration) is
only good for a very few things, for instance declaring pointers.
Yes; pointers work as they have same sizes and we dont allocate memory.
i tried that b4 posting here atfirst and it works fine. that is why i
got confused about forward referencing. if the type is known, why can''t
the compiler do a second pass to allocate the mem ?
the compiler needs to know the size of B in order to generate code
for A, but it does not know the size of B from just the forward declaration.
that is why i asked: Am I not allowed to use forward referencing ? What exactly does the
statement

class B;

in definition of A do? Doesn''t it introduce the typename in A?
i mean doesn''t the compiler do a second pass to get the size and
stuff??
The obvious solution to this is just to reverse the order in which you
define your classes.
hmmmm ..... but still if i define class B outside class A i will get it
exposed to anyone including the header file.

The other solution would be to rewrite A like this

class B;

class A
{
B* b;
};

By using a pointer you would not need to include the definition of B in
the header file at all. This might also help with your other requirement
that B not be usable by itself.

I dont know how by just declaring a pointer in a class can i restrict
B''s usage. could you ellaborate please ?

I did try and implement this with private constructors and friend
functions. However that necessarilly means something else semantically.
i want to implement something like-> A::B always.
Any suggestions? Am I missing something obvious ?



Not obvious



Thnx. cause i was getting pretty worried :)
john



Thnx.
~M


Probably ''pimpl'' idiom can help you:

http://www.gotw.ca/publications/mill04.htm

Bye
Fabio


这篇关于组合关系/前向参考问题。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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