Asked  7 Months ago    Answers:  5   Viewed   35 times

I've been using C++ for a short while, and I've been wondering about the new keyword. Simply, should I be using it, or not?

1) With the new keyword...

MyClass* myClass = new MyClass();
myClass->MyField = "Hello world!";

2) Without the new keyword...

MyClass myClass;
myClass.MyField = "Hello world!";

From an implementation perspective, they don't seem that different (but I'm sure they are)... However, my primary language is C#, and of course the 1st method is what I'm used to.

The difficulty seems to be that method 1 is harder to use with the std C++ classes.

Which method should I use?

Update 1:

I recently used the new keyword for heap memory (or free store) for a large array which was going out of scope (i.e. being returned from a function). Where before I was using the stack, which caused half of the elements to be corrupt outside of scope, switching to heap usage ensured that the elements were in tact. Yay!

Update 2:

A friend of mine recently told me there's a simple rule for using the new keyword; every time you type new, type delete.

Foobar *foobar = new Foobar();
delete foobar; // TODO: Move this to the right place.

This helps to prevent memory leaks, as you always have to put the delete somewhere (i.e. when you cut and paste it to either a destructor or otherwise).

 Answers

41

Method 1 (using new)

  • Allocates memory for the object on the free store (This is frequently the same thing as the heap)
  • Requires you to explicitly delete your object later. (If you don't delete it, you could create a memory leak)
  • Memory stays allocated until you delete it. (i.e. you could return an object that you created using new)
  • The example in the question will leak memory unless the pointer is deleted; and it should always be deleted, regardless of which control path is taken, or if exceptions are thrown.

Method 2 (not using new)

  • Allocates memory for the object on the stack (where all local variables go) There is generally less memory available for the stack; if you allocate too many objects, you risk stack overflow.
  • You won't need to delete it later.
  • Memory is no longer allocated when it goes out of scope. (i.e. you shouldn't return a pointer to an object on the stack)

As far as which one to use; you choose the method that works best for you, given the above constraints.

Some easy cases:

  • If you don't want to worry about calling delete, (and the potential to cause memory leaks) you shouldn't use new.
  • If you'd like to return a pointer to your object from a function, you must use new
Tuesday, June 1, 2021
 
medhybrid
answered 7 Months ago
75

Use as when it's valid for an object not to be of the type that you want, and you want to act differently if it is. For example, in somewhat pseudo-code:

foreach (Control control in foo)
{
    // Do something with every control...

    ContainerControl container = control as ContainerControl;
    if (container != null)
    {
        ApplyToChildren(container);
    }
}

Or optimization in LINQ to Objects (lots of examples like this):

public static int Count<T>(this IEnumerable<T> source)
{
    IList list = source as IList;
    if (list != null)
    {
        return list.Count;
    }
    IList<T> genericList = source as IList<T>;
    if (genericList != null)
    {
        return genericList.Count;
    }

    // Okay, we'll do things the slow way...
    int result = 0;
    using (var iterator = source.GetEnumerator())
    {
        while (iterator.MoveNext())
        {
            result++;
        }
    }
    return result;
}

So using as is like an is + a cast. It's almost always used with a nullity check afterwards, as per the above examples.

Tuesday, August 3, 2021
 
Otiel
answered 4 Months ago
75

The first one creates a Money object on the stack, its lifespan is within the scope of when it was created. Meaning when you hit a } it goes out of scope and the memory is returned. Use this when you want to create an object within one function.

The second one creates a Money object on the heap, its lifespan is as long as you want it to be, namely until you delete it. Use this when you want your object to be passed around to different functions

Saturday, August 7, 2021
 
Nitesh
answered 4 Months ago
40

I suspect you are not calling the new you think you are calling.

This works as you expect.

void *myalloc (size_t) { return 0; }
void * operator new (size_t s) throw() { return myalloc(s); }
struct Foo {
    std::string s;
    Foo () { std::cout << this << std::endl; }
};
int main () {
    Foo *f = new Foo;
    if (f == 0) std::cout << "f is NULL" << std::endl;
}

Where as, this fails.

void *myalloc (size_t) { return 0; }
void * operator new (size_t s) throw() { return myalloc(s); }
struct Foo {
    std::string s;
    Foo () { std::cout << this << std::endl; }
    void * operator new (size_t s) { return myalloc(s); }
};
int main () {
    Foo *f = new Foo;
    if (f == 0) std::cout << "f is NULL" << std::endl;
}
Monday, October 18, 2021
 
Adil Hussain
answered 2 Months ago
29

You have using std::ofstream instead of using std::ostream, so it doesn't know what ostream is.

You also need to include <ostream>.

Really, though, there's no reason to use using anything; you should just qualify the names with the namespace (especially if this is a header file, to avoid polluting the global namespace of other files):

friend std::ostream& operator<< (std::ostream&, const Dog&);
Sunday, November 28, 2021
 
inetbug
answered 1 Week ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share