Solved

C++/CLI default constructor for struct -- error C3417

Posted on 2009-05-06
15
1,267 Views
Last Modified: 2012-06-27
I understand from http://msdn.microsoft.com/en-us/library/ekfb4tkd(VS.80).aspx that the default constructor in the code below is what's tripping the error.

But I need that default constructor ... or something equivalent.  What can I do?

Thanks!
value struct PointFloat {
public:
	PointFloat() {
		X = Y = 0.0f;
	}
	PointFloat(float _X, float _Y) {
		X = _X; Y = _Y;
	}
	float X;
	float Y;
};

Open in new window

0
Comment
Question by:Daniel Wilson
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 3
  • +1
15 Comments
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24321828
C# does not allow default constructor for structs. Change it to a class if you need that, or use the 2nd constructor (float, float)
0
 
LVL 40

Assisted Solution

by:mrjoltcola
mrjoltcola earned 150 total points
ID: 24321851
Eep, this is C++, I read my 2nd question wrong today! :(

But the answer is the same,  because you are mapping the C++ struct to a .NET value type. It is not just C#, it is the .NET CLR that does not allow default no-arg constructors, because the CLR already defines that.

So, why not just use the 2-arg constructor?

Are you compiling in CLI mode on purpose? If you don't need managed C++, then you can just use standard C++ and the above is legal. Its a CLI issue only.

0
 
LVL 9

Accepted Solution

by:
tculler earned 300 total points
ID: 24322654
When you declare something as a "value struct" in Managed C++, this becomes a "managed" struct. Managed Structs and managed classes are nearly identical except for a few major differences:
 - Managed structs are passed by VALUE (i.e, every time you pass one, it "copies" itself)
 - Managed structs do NOT support any form of inheritance, though you can implement interfaces.
 - Though managed structs are copied, the copy is a "shallow" copy, so having any references to classes within one will still point to the same object.

Every time you make a managed struct, it actually generates a default constructor for you. Unfortunately, there is no way around this--any attempt will just cause a compilation error.

By the way, you are aware that there is already a float version of a 2-D point in the System.Drawing namespace (within the System.Drawing.dll assembly) called System.Drawing.PointF, correct? Plus, the floats within that type are fixed, using System.Single instead of C++'s screwy primitive data types.

When a managed struct is created, ALL fields within that struct are immediately initialized to their defualt values--in this case, your default constructor is no different than the one generated by the compiler. They will both assign 0.0F to both X and Y.

Hope that helps,
Nate
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 9

Expert Comment

by:tculler
ID: 24322661
Whoops, forgot to offer a solution. The only real solution is here is to declare your PointFloat struct as a class. In other words, replace "value struct" with "ref class". However, this will force your PointFloat objects to be passed by reference, so keep that in mind. Managed C++ is kinda lame sometimes.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 24322963
>> Managed C++ is kinda lame sometimes.
Sometimes? :)
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24325740
Lame -- well, if you're accustomed to real C++, definitely! When I wrote this for .Net 1.1, C++ permitted some things (bridging managed /unmanaged code) that C# & VB did not.

Do I need it managed?  Yes.  This is a control that drops onto Windows Forms.

>>When a managed struct is created, ALL fields within that struct are immediately initialized to their defualt values--in this case, your default constructor is no different than the one generated by the compiler. They will both assign 0.0F to both X and Y.

Are you sure?  Managed Extensions for C++ (C++ for .Net 1.1) did not initialize all variables.  That gave me some really nasty bugs in this project several years ago.  It would work right in the IDE, then work wrong compiled for Release.

>>By the way, you are aware that there is already a float version of a 2-D point in the System.Drawing namespace (within the System.Drawing.dll assembly) called System.Drawing.PointF

Yes, I am.  I'll probably use that.  I really don't know what I didn't when I wrote this for 1.1.  I may have been unaware of the class at the time.


0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24327371
Not lame if you know what you are dealing with. It is nice of Microsoft to provide us with so many non-standard languages to choose from to keep us from getting too comfortable with cross-platform freedom, like Java or pure C++, however, if you are writing GUIs, trying to be cross-platform ends up making your app LOOK like cross-platform, ie. Java swing apps or Tk apps, or even Qt.

I say, if you are gonna go GUI on Windows, go all in!

But regarding managed C++, when I'm writing for .NET, I choose not to introduce C++ at all, and stick with C#. Otherwise, I'd just prefer to stick with MFC if I'm going to be tracking down C++ problems and managing my memory.

I assume in this case you had reasons, such as a .NET app that had a requirement for something native?
0
 
LVL 40

Assisted Solution

by:evilrix
evilrix earned 50 total points
ID: 24327655
I'm not really down with this managed C++ nonsense, so I'm waiting for mrjoltcola to shoot this down in flames but can't you just have an unmanaged struct and if it needs to be passed into a managed function just wrap it in a managed struct?

Frankly, I just fail to see why Microsoft insist on making life hard for C++ programmers by keep on modifying the semantics of well defined C++ constructs. :(

mrjoltcola... fire away :)
using namespace System;
 
struct foo
{
	foo () : n(0){}
	int n;
};
 
value struct foowrapper
{
	foowrapper(foo & f) : f(f){}
	foo & f;
};
 
void bar(foowrapper ^ f)
{
	f->f.n = 1;
}
 
void bar(foo & f)
{
	f.n = 1;
}
 
int main(array<System::String ^> ^args)
{
	foo f;
	foowrapper fw(f);
 
	bar(f);
	bar(fw);
}

Open in new window

0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24327854
I was ready to load up, looking for my bullets, but I think the wrapper is fine, except we don't really know why the OP wants a value type in the first place, so we won't know if this wrapper will solve anything.

He could just use a single managed class instead, in that case, but I assume since he chose not to, that he wants the value type / call by value semantics for performance or interop reasons.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 24327881
>> so we won't know if this wrapper will solve anything.
That's true... although I think I was throwing it out there more for my interest than anything else :)
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24327895
Honestly, I can't remember why I wrote it that way under .Net 1.1.  Of course it was a __gc struct ... or something like that back then.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 24327940
Ooh, my speculative question became an assisted answer :)
0
 
LVL 40

Expert Comment

by:mrjoltcola
ID: 24327955
With an A+ no doubt!
0
 
LVL 32

Author Comment

by:Daniel Wilson
ID: 24328037
Good discussion of the issue is, to me, valuable assistance.  Of course it wasn't the solution ... but it is valuable.

Thanks to all of you.  If I run into more C++/CLI grief on this project, I'm hoping you see my questions!
0
 
LVL 9

Expert Comment

by:tculler
ID: 24331225
I wasn't trying to rag on Microsoft -- yes, it was great of them to supply a Managed version of C++; I was merely saying it can often be extremely lame :/

Yeah, it *should* initialize all fields to their default values in the default constructor. Keep in mind that reference types' default values are null, not their default constructor (if one is present).
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question