C++ nested classes referencing each other
In C# I can have two nested classes refer to each other without problem:
public class CFGFile
{
class Setting
{
public Entry Ent;
}
class Entry
{
public Setting Setg;
}
}
However, trying the same thing in C++ causes problems:
class CFGFile
{
class Setting;
class Entry
{
Setting Setg;
};
class Setting
{
Entry Ent;
]
};
I get
"incomplete type not allowed"
at the Setg variable definition, and error
"C2079: 'CFGFile::Entry::Setg' uses undefined class
'CFGFile::Setting'"
when compiling.
I'm using Visual Studio 2017.
Is cross referring not possible in nested classes in C++?
c++ class nested visual-studio-2017
add a comment |
In C# I can have two nested classes refer to each other without problem:
public class CFGFile
{
class Setting
{
public Entry Ent;
}
class Entry
{
public Setting Setg;
}
}
However, trying the same thing in C++ causes problems:
class CFGFile
{
class Setting;
class Entry
{
Setting Setg;
};
class Setting
{
Entry Ent;
]
};
I get
"incomplete type not allowed"
at the Setg variable definition, and error
"C2079: 'CFGFile::Entry::Setg' uses undefined class
'CFGFile::Setting'"
when compiling.
I'm using Visual Studio 2017.
Is cross referring not possible in nested classes in C++?
c++ class nested visual-studio-2017
3
Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
– tkausl
Nov 21 '18 at 14:27
@tkausl because in the C# example above, references to objects are being defined, not objects of the class types. I get it. Thanks!
– L Fitz
Nov 21 '18 at 14:46
values cannot beNULL
, so what you wrote is aEntry
containing aSetting
which in turn contains anEntry
which again contains aSetting
which in turn contains anEntry
.... ad infinitum
– user463035818
Nov 21 '18 at 15:02
add a comment |
In C# I can have two nested classes refer to each other without problem:
public class CFGFile
{
class Setting
{
public Entry Ent;
}
class Entry
{
public Setting Setg;
}
}
However, trying the same thing in C++ causes problems:
class CFGFile
{
class Setting;
class Entry
{
Setting Setg;
};
class Setting
{
Entry Ent;
]
};
I get
"incomplete type not allowed"
at the Setg variable definition, and error
"C2079: 'CFGFile::Entry::Setg' uses undefined class
'CFGFile::Setting'"
when compiling.
I'm using Visual Studio 2017.
Is cross referring not possible in nested classes in C++?
c++ class nested visual-studio-2017
In C# I can have two nested classes refer to each other without problem:
public class CFGFile
{
class Setting
{
public Entry Ent;
}
class Entry
{
public Setting Setg;
}
}
However, trying the same thing in C++ causes problems:
class CFGFile
{
class Setting;
class Entry
{
Setting Setg;
};
class Setting
{
Entry Ent;
]
};
I get
"incomplete type not allowed"
at the Setg variable definition, and error
"C2079: 'CFGFile::Entry::Setg' uses undefined class
'CFGFile::Setting'"
when compiling.
I'm using Visual Studio 2017.
Is cross referring not possible in nested classes in C++?
c++ class nested visual-studio-2017
c++ class nested visual-studio-2017
edited Nov 21 '18 at 15:23
Poul Bak
5,43331232
5,43331232
asked Nov 21 '18 at 14:26
L Fitz
284
284
3
Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
– tkausl
Nov 21 '18 at 14:27
@tkausl because in the C# example above, references to objects are being defined, not objects of the class types. I get it. Thanks!
– L Fitz
Nov 21 '18 at 14:46
values cannot beNULL
, so what you wrote is aEntry
containing aSetting
which in turn contains anEntry
which again contains aSetting
which in turn contains anEntry
.... ad infinitum
– user463035818
Nov 21 '18 at 15:02
add a comment |
3
Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
– tkausl
Nov 21 '18 at 14:27
@tkausl because in the C# example above, references to objects are being defined, not objects of the class types. I get it. Thanks!
– L Fitz
Nov 21 '18 at 14:46
values cannot beNULL
, so what you wrote is aEntry
containing aSetting
which in turn contains anEntry
which again contains aSetting
which in turn contains anEntry
.... ad infinitum
– user463035818
Nov 21 '18 at 15:02
3
3
Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
– tkausl
Nov 21 '18 at 14:27
Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
– tkausl
Nov 21 '18 at 14:27
@tkausl because in the C# example above, references to objects are being defined, not objects of the class types. I get it. Thanks!
– L Fitz
Nov 21 '18 at 14:46
@tkausl because in the C# example above, references to objects are being defined, not objects of the class types. I get it. Thanks!
– L Fitz
Nov 21 '18 at 14:46
values cannot be
NULL
, so what you wrote is a Entry
containing a Setting
which in turn contains an Entry
which again contains a Setting
which in turn contains an Entry
.... ad infinitum– user463035818
Nov 21 '18 at 15:02
values cannot be
NULL
, so what you wrote is a Entry
containing a Setting
which in turn contains an Entry
which again contains a Setting
which in turn contains an Entry
.... ad infinitum– user463035818
Nov 21 '18 at 15:02
add a comment |
3 Answers
3
active
oldest
votes
This has nothing to do with nested
or not. In C++, you can not cross reference each other for two classes/structs like that. The workaround is that you use either pointer or reference which does not require a complete type definition. In your case, try the following,
class CFGFile
{
class Setting;
class Entry
{
Setting* Setg; // or std::unique_ptr<Setting> Setg;
};
class Setting
{
Entry Ent;
};
};
As suggested by @Ted Lyngmo, std::unique_ptr
is the preferred way in modern C++ for applications.
Perhaps a suggestion to usestd::unique_ptr<Setting> Setg;
would be good.
– Ted Lyngmo
Nov 21 '18 at 14:43
Using pointers for cross references. Thanks!
– L Fitz
Nov 21 '18 at 14:46
add a comment |
To expand on why this happens, this comes from the fact that when the compiler looks at a struct or class, it needs to be able to determine its exact size, among other things to be able to know how much memory it needs to allocate for instances of these.
In this case, the compiler can't determine the size of Entry
because it only knows that a Setting
class exists, but it doesn't know its size yet.
Using a pointer, i.e.:
class Setting;
class Entry
{
Setting* Setg;
};
actually solves this problem, because while the compiler still doesn't know anything about Setting
, it still knows the size of a pointer (regardless of the pointee's type).
As already mentioned, the "nested" part has no impact on this.
add a comment |
C# - by design - uses reference semantics for classes, thus the provided snippet does not cause circular value depency. OTH c++ prefers value semantics , which would -in turn- result in infinite recursion in the original sample code, if the standard did not ban that kind of code; As implicated in earlier replies, if reference semantics is needed, it should be explicitly expressed in terms of pointer/reference syntax.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53414238%2fc-nested-classes-referencing-each-other%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
This has nothing to do with nested
or not. In C++, you can not cross reference each other for two classes/structs like that. The workaround is that you use either pointer or reference which does not require a complete type definition. In your case, try the following,
class CFGFile
{
class Setting;
class Entry
{
Setting* Setg; // or std::unique_ptr<Setting> Setg;
};
class Setting
{
Entry Ent;
};
};
As suggested by @Ted Lyngmo, std::unique_ptr
is the preferred way in modern C++ for applications.
Perhaps a suggestion to usestd::unique_ptr<Setting> Setg;
would be good.
– Ted Lyngmo
Nov 21 '18 at 14:43
Using pointers for cross references. Thanks!
– L Fitz
Nov 21 '18 at 14:46
add a comment |
This has nothing to do with nested
or not. In C++, you can not cross reference each other for two classes/structs like that. The workaround is that you use either pointer or reference which does not require a complete type definition. In your case, try the following,
class CFGFile
{
class Setting;
class Entry
{
Setting* Setg; // or std::unique_ptr<Setting> Setg;
};
class Setting
{
Entry Ent;
};
};
As suggested by @Ted Lyngmo, std::unique_ptr
is the preferred way in modern C++ for applications.
Perhaps a suggestion to usestd::unique_ptr<Setting> Setg;
would be good.
– Ted Lyngmo
Nov 21 '18 at 14:43
Using pointers for cross references. Thanks!
– L Fitz
Nov 21 '18 at 14:46
add a comment |
This has nothing to do with nested
or not. In C++, you can not cross reference each other for two classes/structs like that. The workaround is that you use either pointer or reference which does not require a complete type definition. In your case, try the following,
class CFGFile
{
class Setting;
class Entry
{
Setting* Setg; // or std::unique_ptr<Setting> Setg;
};
class Setting
{
Entry Ent;
};
};
As suggested by @Ted Lyngmo, std::unique_ptr
is the preferred way in modern C++ for applications.
This has nothing to do with nested
or not. In C++, you can not cross reference each other for two classes/structs like that. The workaround is that you use either pointer or reference which does not require a complete type definition. In your case, try the following,
class CFGFile
{
class Setting;
class Entry
{
Setting* Setg; // or std::unique_ptr<Setting> Setg;
};
class Setting
{
Entry Ent;
};
};
As suggested by @Ted Lyngmo, std::unique_ptr
is the preferred way in modern C++ for applications.
edited Nov 21 '18 at 14:50
answered Nov 21 '18 at 14:31
CS Pei
8,3801938
8,3801938
Perhaps a suggestion to usestd::unique_ptr<Setting> Setg;
would be good.
– Ted Lyngmo
Nov 21 '18 at 14:43
Using pointers for cross references. Thanks!
– L Fitz
Nov 21 '18 at 14:46
add a comment |
Perhaps a suggestion to usestd::unique_ptr<Setting> Setg;
would be good.
– Ted Lyngmo
Nov 21 '18 at 14:43
Using pointers for cross references. Thanks!
– L Fitz
Nov 21 '18 at 14:46
Perhaps a suggestion to use
std::unique_ptr<Setting> Setg;
would be good.– Ted Lyngmo
Nov 21 '18 at 14:43
Perhaps a suggestion to use
std::unique_ptr<Setting> Setg;
would be good.– Ted Lyngmo
Nov 21 '18 at 14:43
Using pointers for cross references. Thanks!
– L Fitz
Nov 21 '18 at 14:46
Using pointers for cross references. Thanks!
– L Fitz
Nov 21 '18 at 14:46
add a comment |
To expand on why this happens, this comes from the fact that when the compiler looks at a struct or class, it needs to be able to determine its exact size, among other things to be able to know how much memory it needs to allocate for instances of these.
In this case, the compiler can't determine the size of Entry
because it only knows that a Setting
class exists, but it doesn't know its size yet.
Using a pointer, i.e.:
class Setting;
class Entry
{
Setting* Setg;
};
actually solves this problem, because while the compiler still doesn't know anything about Setting
, it still knows the size of a pointer (regardless of the pointee's type).
As already mentioned, the "nested" part has no impact on this.
add a comment |
To expand on why this happens, this comes from the fact that when the compiler looks at a struct or class, it needs to be able to determine its exact size, among other things to be able to know how much memory it needs to allocate for instances of these.
In this case, the compiler can't determine the size of Entry
because it only knows that a Setting
class exists, but it doesn't know its size yet.
Using a pointer, i.e.:
class Setting;
class Entry
{
Setting* Setg;
};
actually solves this problem, because while the compiler still doesn't know anything about Setting
, it still knows the size of a pointer (regardless of the pointee's type).
As already mentioned, the "nested" part has no impact on this.
add a comment |
To expand on why this happens, this comes from the fact that when the compiler looks at a struct or class, it needs to be able to determine its exact size, among other things to be able to know how much memory it needs to allocate for instances of these.
In this case, the compiler can't determine the size of Entry
because it only knows that a Setting
class exists, but it doesn't know its size yet.
Using a pointer, i.e.:
class Setting;
class Entry
{
Setting* Setg;
};
actually solves this problem, because while the compiler still doesn't know anything about Setting
, it still knows the size of a pointer (regardless of the pointee's type).
As already mentioned, the "nested" part has no impact on this.
To expand on why this happens, this comes from the fact that when the compiler looks at a struct or class, it needs to be able to determine its exact size, among other things to be able to know how much memory it needs to allocate for instances of these.
In this case, the compiler can't determine the size of Entry
because it only knows that a Setting
class exists, but it doesn't know its size yet.
Using a pointer, i.e.:
class Setting;
class Entry
{
Setting* Setg;
};
actually solves this problem, because while the compiler still doesn't know anything about Setting
, it still knows the size of a pointer (regardless of the pointee's type).
As already mentioned, the "nested" part has no impact on this.
answered Nov 21 '18 at 14:56
JBL
9,70333667
9,70333667
add a comment |
add a comment |
C# - by design - uses reference semantics for classes, thus the provided snippet does not cause circular value depency. OTH c++ prefers value semantics , which would -in turn- result in infinite recursion in the original sample code, if the standard did not ban that kind of code; As implicated in earlier replies, if reference semantics is needed, it should be explicitly expressed in terms of pointer/reference syntax.
add a comment |
C# - by design - uses reference semantics for classes, thus the provided snippet does not cause circular value depency. OTH c++ prefers value semantics , which would -in turn- result in infinite recursion in the original sample code, if the standard did not ban that kind of code; As implicated in earlier replies, if reference semantics is needed, it should be explicitly expressed in terms of pointer/reference syntax.
add a comment |
C# - by design - uses reference semantics for classes, thus the provided snippet does not cause circular value depency. OTH c++ prefers value semantics , which would -in turn- result in infinite recursion in the original sample code, if the standard did not ban that kind of code; As implicated in earlier replies, if reference semantics is needed, it should be explicitly expressed in terms of pointer/reference syntax.
C# - by design - uses reference semantics for classes, thus the provided snippet does not cause circular value depency. OTH c++ prefers value semantics , which would -in turn- result in infinite recursion in the original sample code, if the standard did not ban that kind of code; As implicated in earlier replies, if reference semantics is needed, it should be explicitly expressed in terms of pointer/reference syntax.
answered Nov 21 '18 at 15:29
Red.Wave
72737
72737
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53414238%2fc-nested-classes-referencing-each-other%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
– tkausl
Nov 21 '18 at 14:27
@tkausl because in the C# example above, references to objects are being defined, not objects of the class types. I get it. Thanks!
– L Fitz
Nov 21 '18 at 14:46
values cannot be
NULL
, so what you wrote is aEntry
containing aSetting
which in turn contains anEntry
which again contains aSetting
which in turn contains anEntry
.... ad infinitum– user463035818
Nov 21 '18 at 15:02