POV-Ray : Newsgroups : povray.off-topic : Undirected ramblings on C++ : Re: Undirected ramblings on C++ Server Time
28 Jul 2024 12:32:29 EDT (-0400)
  Re: Undirected ramblings on C++  
From: Warp
Date: 28 Feb 2014 09:16:52
Message: <53109a54@news.povray.org>
Orchid Win7 v1 <voi### [at] devnull> wrote:
>    struct Side
>    {
>      Pattern & Pattern;
>      Pattern::iterator Iterator;
>    }

I think you are misunderstanding what C++ references are. They are *not*
like Java references.

While internally references might be pointers, you should stop thinking
about them as such. As I said in my previous post, references are
effectively "aliases". In other words, a name that's an alias to an
object.

References must always be initialized to something and they cannot be
later changed to be an alias to something else. You can't have "null
references", nor uninitialized references.

While it's possible to have a reference as a member of a struct/class,
it's seldom useful. (There *are* some cases where it can be useful, but
it tends to be rare.) The reference must always be initialized, and it
can never be changed again. The former means that if you have a reference
member you have to write a constructor that initializes it. The latter
means that the class becomes non-assignable.

You are clearly trying to use references to make something like a
list/tree node. References cannot really be used for that in a sensible
manner (because as said the node becomes non-assignable and you can't
have "null references".) Such nodes are usually done with pointers instead.

As you should be well aware, you shouldn't start messing with pointers
in C++ unless you know what you are doing.

Also references can be misused. C++ is not gargabe-collected. It's not
guaranteed that the object that the reference is pointing to will remain
for as long as the reference does. (For example returning a reference to
a local object is possible, but undefined behavior. Don't do things like
that. Your program will just crash.)

If you can, use one of the standard library data containers. Writing your
own dynamic data container is error-prone if you don't have enough C++
experience.

> Every single line that declares a State variable gives me C2512. As you 
> can see, I clearly *have not* defined any constructors, so that isn't 
> the reason for a default constructor not existing.

The compiler cannot create a constructor because it doesn't know what
the reference should be initialized with.

Your fundamental problem is that you are trying to use references for
something they aren't meant for.

> So what you're saying is, a reference is a pointer where you can't ever 
> change the *address* it points to, but you can change what's *at* that 
> address?

It may be like that inside, but you should really just think of it as an
"alias" of the thing it's referring to. Whatever you do to the reference
you are doing to the original object.

> Does that also mean that assigning one vector to another actually 
> *copies* the entire vector? As in, a deep copy??

Like all standard data containers, they are handled by value. Assigning
one container object to another makes a deep copy.

This is not Java.

> I didn't mean references specifically. I just meant the entire language. 
> Nobody would try to claim that C++ is small or simple or free of 
> surprises. For example,

>     struct Side
>     {
>       Pattern & ThePattern;
>       Side(Pattern p) : ThePattern(p) {}
>     }

You should understand what's happening here.

The constructor is taking an object *by value*, which means that inside
the constructor 'p' is a temporary object (which will disappear when
the constructor ends.) You are then making 'ThePattern' a reference to
said temporary value. Then the constructor ends and... 'ThePattern' refers
to a non-existeng object. Crash.

You seem to be programming this like it were Java. C++ isn't.

Try to stop using references or pointers if you can. If you can't, then
try to use the standard data containers. If you absolutely *must* make
your own dynamic data container... well, you are going to make errors.

Does 'ThePattern' need to point to some other object, or can it simply
contain a *copy* of that object? If it can contain a copy, then make it
a non-reference. Then 'p' will be simply copied to it, and everything will
be fine and dandy.

> Today it's references. Last time it was

>    catch (std::exception e)
>    {
>      std::cout << e.what();
>    }

> which *always* says std::exception, even if that wasn't the exception 
> thrown.

I don't understand where you are getting at.

> The time before that, it was a memory leak due to an (empty) 
> destructor not being virtual.

I think one of the major problems you are having is that you insist in
allocating things dynamically and having pointers to them (instead of
using eg. smart pointers or just using the standard data containers.)

I code in C++ almost every day as my payjob. I write thousands and thousands
of likes of C++ code every year. Do you know when was the last time I wrote
the keywords 'new' or 'delete'? I don't even remember. It must have been
years.

A surprising amount of problems can be solved without ever writing a
single 'new' or 'delete', or having dangerous raw pointers pointing to
stuff. Most things can be handled by value, and 99% of dynamic data
managing can be used by using purely the standard data containers.

-- 
                                                          - Warp


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.