Jump to content

  • Log In with Google      Sign In   
  • Create Account


Why "double declare" classes? (Lack of better terminology)


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
20 replies to this topic

#1 Aspirer   Members   -  Reputation: 544

Like
0Likes
Like

Posted 11 December 2013 - 10:40 PM

I tried google, but can't find a good way to ask this question... lol

 

For instance:

 

myClass anObject = new myClass;

 

 

Why do you declare a myClass, then specify "new myClass"

 

In my mind, it's the same as:

int myNumber = new int.

 

"No shit, it's a new int! If I wanted a f***ing float, it woulda said 'FLOAT myNumber'!!!"

If I wanted a "new yourClass", I would've typed "yourClass anObject"

 

 

 

 

And for that matter, what would be a good search phrase to find info on this, cause "why double declare class" and "why declare a class instance as new" and all the related phrases that come to mind don't turn up a damn thing....

 

Thanks, cause this is really bugging the shit outta me.


Edited by Aspirer, 11 December 2013 - 10:42 PM.


Sponsor:

#2 SiCrane   Moderators   -  Reputation: 9559

Like
1Likes
Like

Posted 11 December 2013 - 10:43 PM

Well, most languages have evolved so that you don't actually need to do that. Ex C# has had the var keyword since 3.0 and C++11 introduced the use of the auto keyword to implicitly define a type.



#3 Aspirer   Members   -  Reputation: 544

Like
0Likes
Like

Posted 11 December 2013 - 10:57 PM

Well, what brought it up was reading up on using lists in Unity, and their example was

 

 List<T> myList = new List<T>();

 

To me, it should be a no brainer, "Hey, I said myList was "List<T>" so it should probably be a "new List<T>"



#4 Nik02   Crossbones+   -  Reputation: 2768

Like
0Likes
Like

Posted 11 December 2013 - 10:59 PM

In implicitly typed C# syntax, that would be expressed as "var myList = new List<T>();", and would be exactly equivalent in the subsequent code.


Niko Suni


#5 Hodgman   Moderators   -  Reputation: 29464

Like
4Likes
Like

Posted 11 December 2013 - 11:19 PM

In C++ you'd write:

int anInt;
myClass anObject;

or for a pointer to an object (can by null) in C++98:

int* anIntPointer = new int;
myClass* aClassPointer = new myClass;

or in C++11 you can make the above not repeat itself:

auto anIntPointer = new int;
auto aClassPointer = new myClass;


#6 dawgdog   Members   -  Reputation: 174

Like
18Likes
Like

Posted 11 December 2013 - 11:32 PM

Say you have a Base class and a derived class. Unless I'm mistaken, the following code is valid

Base base=new Derived;


#7 Nypyren   Crossbones+   -  Reputation: 4162

Like
6Likes
Like

Posted 12 December 2013 - 12:45 AM

Say you have a Base class and a derived class. Unless I'm mistaken, the following code is valid




Base base=new Derived;

Precisely. This is the main reason that prevents type declarations from being eradicated entirely in statically typed languages. Even "var" and "auto" are picking a specific static type. They just allow you to use them to reduce typing.

If you use C#, use 'var' to reduce redundant typing, ESPECIALLY for long types like Dictionary<string,object>. But don't forget that being able to designate a variable's type manually when you need to is also very important.

Edited by Nypyren, 12 December 2013 - 12:46 AM.


#8 NightCreature83   Crossbones+   -  Reputation: 2738

Like
1Likes
Like

Posted 12 December 2013 - 03:28 AM

 

In C++ you'd write:

int anInt;
myClass anObject;

or for a pointer to an object (can by null) in C++98:

int* anIntPointer = new int;
myClass* aClassPointer = new myClass;

or in C++11 you can make the above not repeat itself:

auto anIntPointer = new int;
auto aClassPointer = new myClass;

And in C++14 you can write this as long as the range supports a push_back method of value type

auto add_value_to_range(auto range, auto value) { range.push_back(value); return true; }

Edited by NightCreature83, 12 December 2013 - 03:28 AM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#9 kiteflyingmonkey   Members   -  Reputation: 310

Like
0Likes
Like

Posted 12 December 2013 - 05:51 AM

 

Say you have a Base class and a derived class. Unless I'm mistaken, the following code is valid

Base base=new Derived;

 

An example of this is that you might want to have a for loop that goes through all of your Shapes and changes their colour to green. The Shape class has a colour, and derrived classes like Square and Circle have what ever extra properties they need. You would have an array of type shape that contains Cirles and Squares.

Shape [] arr = new Shape [2];
arr[0] = new Circle();
arr[1] = new Square();

for(int i = 0; i < arr.length; ++i) {
    arr[i].setColour(GREEN);
}


#10 Leandro GR   Members   -  Reputation: 497

Like
2Likes
Like

Posted 12 December 2013 - 07:19 AM

Speaking of C# that's because variable declaration and object instantiation are two different things

Here we are just declaring a variable of type List<T>
List<T> myList;

It has no value, and is not initialized, it can't be used unless it's used in an out parameter

What would happen if it automatically create a new instance of the object just by declaring it? If it was a value type, like an int or float there would be no problem at all, but it would never work for a reference type.

First of all a reference type may not have a parameterless constructor, or it could be an abstract class or even an Interface, there would be no way to initialize then this way, or it could have no public constructors at all, what if it uses some kind of factory class to initialize the objects?

And of course, what if you just want the variable to receive an instance from somewhere else? You do not always want a new object, sometimes you will receive it as a parameter or from calling some other function

So you say it's a "List<T>", but how can the compiler know you really want a "new List<T>" and not an existing one, or some other object that inherits from List<T>? What if you really want a new List<T> but you want it to be created by a function that initializes it with some values?

#11 haansn08   Members   -  Reputation: 172

Like
0Likes
Like

Posted 12 December 2013 - 08:46 AM

 

Say you have a Base class and a derived class. Unless I'm mistaken, the following code is valid

Base base=new Derived;

 

Yes - and it's not just valid it's also good practice:

http://www.fatagnus.com/program-to-an-interface-not-an-implementation/

 

And you can type var (C#) or auto (C++) or whatever if you want the compliler to recognize the type automatically.

(But it disguises the type e.g. if the return value of a function is not clear.)


Edited by haansn08, 12 December 2013 - 08:49 AM.


#12 LorenzoGatti   Crossbones+   -  Reputation: 2662

Like
0Likes
Like

Posted 12 December 2013 - 11:27 AM

&nbsp;

Well, what brought it up was reading up on using lists in Unity, and their example was
&nbsp;
&nbsp;List&lt;T&gt;&nbsp;myList = new List&lt;T&gt;();
&nbsp;
To me, it should be a no brainer, "Hey, I said myList was "List&lt;T&gt;" so it should probably be a "new List&lt;T&gt;"

It's the other way around: expressions (here new List(), the constructor) have a definite type (here List), and it can be inferred that the same type as the expression is a valid default choice for the type of a variable that is meant to hold the value of the expression. This is what allows syntax like "var" in C# and "auto" in C++.
Produci, consuma, crepa

#13 Servant of the Lord   Crossbones+   -  Reputation: 18496

Like
1Likes
Like

Posted 12 December 2013 - 01:18 PM

And in C++14 you can write this as long as the range supports a push_back method of value type

auto add_value_to_range(auto range, auto value) { range.push_back(value); return true; }


In templates only, or regular functions? That seems like it'd have to be a compile-time template.
The return value makes sense (and is already supported in C++11, but is being refined in C++14), but as parameters, if the function is overloaded, that seems like it'd introduce ambiguity. Are auto parameters the last to be resolved only if the other overloads don't match?
It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#14 Servant of the Lord   Crossbones+   -  Reputation: 18496

Like
1Likes
Like

Posted 12 December 2013 - 01:20 PM

C++ examples of why the syntax needs to support having them on both sides:

//As dawgdog mentioned
MyBase *base = new MyDerived();

MyType type; //Left-hand side needed, because no right hand is specified.

//Right-hand needed, because no left hand is specified.
myFunction(MyType());

//Unnecessarily redundant, but validly. Type on both sides.
MyType type = MyType();

//Left-hand needed, but since it's already present you can just use auto (as others already mentioned).
auto type = MyType();

It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#15 NightCreature83   Crossbones+   -  Reputation: 2738

Like
1Likes
Like

Posted 12 December 2013 - 02:34 PM

 

And in C++14 you can write this as long as the range supports a push_back method of value type

auto add_value_to_range(auto range, auto value) { range.push_back(value); return true; }
In templates only, or regular functions? That seems like it'd have to be a compile-time template.
The return value makes sense (and is already supported in C++11, but is being refined in C++14), but as parameters, if the function is overloaded, that seems like it'd introduce ambiguity. Are auto parameters the last to be resolved only if the other overloads don't match?

 

It's regular functions and even lambda captures, thats the whole reason for it. This explains better: http://herbsutter.com/2013/06/13/gotw-93-solution-auto-variables-part-2/

 

Example code from article in base form:

function<void(vector<int>)> get_size =
     [](const vector<int>& x) { return x.size(); };

Rewritten to use auto:

auto get_size = [](const auto& x) { return x.size(); };

this will work for any object passed to the lambda that has a size() function defined for it. It pretty much allows you to write duck typed code in C++ smile.png


Edited by NightCreature83, 12 December 2013 - 02:35 PM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, Mad Max

#16 jHaskell   Members   -  Reputation: 989

Like
1Likes
Like

Posted 12 December 2013 - 02:38 PM

I'm assuming you're referring to C# here since all the examples you've mentioned look C#ish and not C++ish, and you mention Unity, which has no C++ implementation. though you may be referring to Java as well.

 

In C# all variables full under two categories.  The narrow category of Value types, which are all the built-in primitives (int, float, char, etc), and the much broader category of Reference types which is any class or template type.

 

If you're most familiar with C++ it's easiest to think of Value types as variables on the stack and Reference types as variables on the Heap.  And as any variable on the Heap in C++ must be Instantiated with new, so must any Reference variable in C# be instantiated.  Unlike C++,  Reference types can only be instantiated on the heap.  There's no way to automatically create a local instance of a Reference type.



#17 Servant of the Lord   Crossbones+   -  Reputation: 18496

Like
0Likes
Like

Posted 12 December 2013 - 04:58 PM

In templates only, or regular functions? That seems like it'd have to be a compile-time template.
The return value makes sense (and is already supported in C++11, but is being refined in C++14), but as parameters, if the function is overloaded, that seems like it'd introduce ambiguity. Are auto parameters the last to be resolved only if the other overloads don't match?

It's regular functions and even lambda captures, thats the whole reason for it. This explains better: http://herbsutter.com/2013/06/13/gotw-93-solution-auto-variables-part-2/
 
Example code from article in base form:
function<void(vector<int>)> get_size =
     [](const vector<int>& x) { return x.size(); };
Rewritten to use auto:
auto get_size = [](const auto& x) { return x.size(); };
this will work for any object passed to the lambda that has a size() function defined for it. It pretty much allows you to write duck typed code in C++ smile.png

I can't see where the linked article talks about auto parameters in normal overloaded functions, am I missing something?
Return values, yes. C++11 has that in some limited cases already.
Template arguments, yes, that makes sense. Lambda arguments make sense (lambda auto parameters could be compiled as templated arguments), but normal C-style C++ functions can't change their arguments... Are auto-parameterized functions secretly template functions in disguise, generating additional compile-time overloads?

Edited by Servant of the Lord, 12 December 2013 - 05:03 PM.

It's perfectly fine to abbreviate my username to 'Servant' rather than copy+pasting it all the time.
All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.
Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal

[Fly with me on Twitter] [Google+] [My broken website]

[Need web hosting? I personally like A Small Orange]


#18 frob   Moderators   -  Reputation: 20238

Like
7Likes
Like

Posted 12 December 2013 - 05:41 PM

Well, what brought it up was reading up on using lists in Unity, and their example was

List<T> myList = new List<T>();

To me, it should be a no brainer, "Hey, I said myList was "List<T>" so it should probably be a "new List<T>"

If you are coming from a C or C++ background, know that C# is a different language.

If it helps you transition, you can think that in languages like Java and C# all variables are secretly pointers. They don't look like pointers, but myList is really a pointer to List<T>. If you type SomeObject obj; the equivalent C++ would be SomeObject *obj;, a pointer rather than an instance.

Again if it helps to make the transition, think of it as a conspiracy. The writers of these new languages don't want you to know about pointers. They want you to forget pointers even existed. So variables are really pointers to objects rather than objects; instead of the -> operator on these secret pointers they use the . operator to try to confuse you. That's also why the languages use dot for scope resolution rather than ::, to make you forget about your true roots, trying to tempt you with an easier way rather than the true path of hard work and struggles.

Once you are indoctrinated to the secret cult of modern programming languages you might discover that it frees your mind to work on other more important issues. But for now, they are just trying to cover up the truth. Pointers are hidden to just use a dot. Scope is hidden to just use a dot. Who knows what critical truths of programming they will hide next behind the dot.

Be careful about drinking from the punch bowl, because until you do you can rest assured that there are serious performance penalties for hiding pointers, that hiding pointers this way will upset every performance metric, and that every time a pointer is hidden this way a puppy gets drowned. This is why it is important to stick with C and C++ that have their roots in 1950's model, rather than those hippie/punk/goth kids using languages with a 1990's model. If you are forced to use their languages, always remember that you really are dealing with pointers when they want you to think you have objects.

Until your mind makes the transition, know that in these sneaky modern languages everything is secretly a pointer, to appease the secret pointer objects must be made with <i>new</i>, and they want to deny the existence of <i>delete</i>. They are a cult of satan using a powerful drug, be careful when working with the code lest it addict you. :)
Check out my personal indie blog at bryanwagstaff.com.

#19 pcmaster   Members   -  Reputation: 659

Like
0Likes
Like

Posted 13 December 2013 - 07:29 AM

Frob, this was the single most funny thing I read here in weeks :D ROFL



#20 Álvaro   Crossbones+   -  Reputation: 12917

Like
2Likes
Like

Posted 13 December 2013 - 08:38 AM

That was kind of funny, but it's actually more informative than funny. I do wish people that learn Java as a first language would know that much, so they have a mental picture of what's likely to happen under the hood, and therefore make reasonable estimates of the performance some way of implementing something will have.

 

In particular, I seem to encounter a lot of people trying to write an alpha-beta searcher (chess, checkers, connect-4...) in Java, and they don't understand why their programs are two orders of magnitude slower than commercial programs. The answer is typically that they are doing a whole bunch of dynamic memory allocations per node visited, which is unacceptably slow. And yes, for some types of programs (the vast majority of the programs I care about) performance still matters, certainly in the two-orders-of-magnitude scale.

 

 

I was going to ask what mechanisms in Java and C# I should recommend to people with this problem, but I think that would be too much of a thread hijack. I'll ask whenever I find someone with that problem again.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS