-1

Edit: Thanks all. Lots of great info to go over. Will take me a while to absorb.

After 10+ years of an unhealthy romance with programming, I think I'm finally getting my head around pointers. But I'm still not comfortable with them.

I have some relatively simple code:

#include <iostream>
#include <string.h>

using namespace std;

class MyString
{
private:
    char* buffer;

public:
    //Constructor
    MyString(const char* initString)
    {
        if(initString != NULL)
        {
            buffer = new char[strlen(initString)+1];
            strcpy(buffer, initString);
        }
        else
            buffer = NULL;
    }
    //Destructor
    ~MyString()
    {
        cout << "Invoking destructor, clearing up\n";
        if (buffer != NULL)
            delete [] buffer;
    }

    int GetLength()
    {
        return strlen(buffer);
    }

    const char* GetString()
    {
        return buffer;
    }
};

int main()
{
    MyString SayHello("Hello from String Class");
    cout << "String buffer in MyString is " << SayHello.GetLength();
    cout << " characters long\n";

    cout << "Buffer contains: " << SayHello.GetString() << endl;

    return 0;
}

Why does MyString wish to make a pointer from the first argument (in main()?) Why doesn't it just pass by copy? or use the address of operator?

Am I asking the 'wrong question'? Not seeing something clearly?

Many thanks. Hope the question is clear.

aName
  • 257
  • 2
  • 8
  • 1
    Unrelated, yet very related: https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three/4172961 – UKMonkey Apr 08 '19 at 15:14
  • 1
    Arrays can't be passed by value. You either need to pass them by reference (but that usually requires templates) or use their implicit decay-into-pointer property to instead pass a pointer to the first element. Use a `std::array` wrapper instead if you want an array that has more intuitive value semantics. – François Andrieux Apr 08 '19 at 15:16
  • 1
    In modern C++ pointers are used mostly for interop with C. – user7860670 Apr 08 '19 at 15:17
  • @VTT Even in modern c++ only projects you still use raw pointers at many place. You use them (or references) when you pass an object, but you don’t transphere its ownership. So basically for all utility functions you normally pass the raw pointer or a reference to the object that is managed by a smart pointer. – t.niese Apr 08 '19 at 15:22
  • @t.niese *"you still use raw pointers at many place. You use them when when you pass an object, but you don’t transphere its owner ship"* - that is where references should be used (or optional reference for nullability). There could be no "or" when selecting between pointer and reference. – user7860670 Apr 08 '19 at 15:25
  • @VTT I prefer `gsl::observer` over `std::optional>` – Caleth Apr 08 '19 at 15:33
  • @Caleth Isn't it called `gsl::observer_ptr`? I prefer to use third-party policy-based wrappers `t_Reference ...` – user7860670 Apr 08 '19 at 15:41
  • @VTT probably, or just `T *` – Caleth Apr 08 '19 at 15:52
  • Use `` in C++, not ``. – eesiraed Apr 08 '19 at 21:46

2 Answers2

1

It does not.
String literals are just a sequence of characters somewhere in the memory. They are not wrapped by some object.
An object like MyString or std::string may act as a wrapper object and have a way to copy them or change them.
But a string literal is just memory. Sequence of characters that ends with '\0'. They cannot be changed so the way to access them is a const char*.

This is passing a string literal by poiter which is fairy fast. You may accept std::string which has explicit constructor and will create an std::string string object from the string literal.

Passing by reference(&), on the other hand, is fairly different concept. It is like passing the object. No copy, no pointer(it might be done with pointer by the compiler but you should not think about that).

Petar Velev
  • 2,305
  • 12
  • 24
1

Why does MyString wish to make a pointer from the first argument (in main()?)

Because arrays transform into pointers at the slightest provocation, and "" literals are const char arrays.

Why doesn't it just pass by copy?

Because you can't assign or copy a C-style array.

or use the address of operator?

There is an implicit conversion from const char[23] to const char *.

Aside:

In c++, the null pointer is spelled nullptr, you can safely delete[] one, and there is an implicit copy constructor and copy assignment operator generated for MyString, which will lead to double delete[]s of buffer

Caleth
  • 52,200
  • 2
  • 44
  • 75