Когда функция / метод должен запросить * или & - PullRequest
0 голосов
/ 08 апреля 2019

Редактировать: Спасибо всем.Много отличной информации, чтобы перейти.Мне понадобится время, чтобы поглотить.

После 10 с лишним лет нездорового романа с программированием, я думаю, что я наконец разбираюсь в указателях.Но я до сих пор не доволен ими.

У меня есть относительно простой код:

#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;
}

Почему MyString хочет сделать указатель из первого аргумента (в main()?) Почему бы просто не пройти мимо копии?или использовать адрес оператора?

Я задаю «неправильный вопрос»?Не видите что-то ясно?

Большое спасибо.Надеюсь, вопрос ясен.

Ответы [ 2 ]

1 голос
/ 08 апреля 2019

Почему MyString хочет сделать указатель из первого аргумента (в main ()?)

Поскольку массивы преобразуются в указатели при малейшей провокации, а литералы ""const char массивов.

Почему бы просто не пройти мимо копии?

Поскольку вы не можете назначить или скопировать массив в стиле C.

или использовать адрес оператора?

Существуетнеявное преобразование из const char[23] в const char *.

В сторону:

В C ++ нулевой указатель пишется nullptr, вы можете безопасно delete[] один, и есть неявный конструктор копирования и оператор назначения копирования, сгенерированный для MyString, что приведет к удвоению delete[] с buffer

1 голос
/ 08 апреля 2019

Это не так.
Строковые литералы - это просто последовательность символов где-то в памяти. Они не обернуты каким-либо предметом.
Объект типа MyString или std::string может выступать в качестве объекта-обертки и может копировать или изменять его.
Но строковый литерал - это просто память. Последовательность символов, которая заканчивается на '\0'. Они не могут быть изменены, поэтому способ доступа к ним - const char*.

Это передача строкового литерала на poiter, что очень быстро. Вы можете принять std::string, который имеет явный конструктор и создаст строковый объект std::string из строкового литерала.

Передача по ссылке (&), с другой стороны, является довольно другой концепцией. Это похоже на прохождение объекта. Нет копии, нет указателя (это может быть сделано с указателем компилятором, но вам не следует об этом думать).

...