Вопросы по C ++: указатели / адреса памяти и подклассы - PullRequest
4 голосов
/ 31 января 2010

Почему мы можем использовать этот код:

int* FunctionB(int x)
{
    int temp =30;

    //more code

    return &temp;
}

Мне кажется, что я не возвращаю то, что сказал. Почему адрес памяти может быть возвращен, если я объявил возвращаемый тип указателем? Разве указатель не является чем-то, что указывает на адрес памяти, а не адресом памяти?


class Image : public BMP
{
    public:
    void invertcolors();
    void flipleft();
    void adjustbrightness(int r,int g,int b);

    private:
};

При компиляции предыдущего кода я получаю эту ошибку:

image.h:3: error: expected class-name before ‘{’ token

но я думал, что использовал правильный синтаксис для объявления подкласса. Что-то не так с тем, что я написал?

Ответы [ 4 ]

4 голосов
/ 31 января 2010

Что касается вашего первого вопроса

Почему нам разрешено запускать этот код:

Ничто не может помешать вам вернуть адрес локальной переменной, но это опасно (запомните мои слова). Фактический адрес возврата или ссылка на локальную переменную вызывает Неопределенное поведение (это означает, что может произойти все что угодно).

Также взгляните на this.

Почему адрес памяти может быть возвращен, если я объявил возвращаемый тип указателем?

Это означает, что вы должны изучать основы указателей. В информатике указатель - это тип данных языка программирования, значение которого относится непосредственно (или «указывает») к другому значению, хранящемуся в другом месте в памяти компьютера , используя его адрес .

.. но я думал, что использовал правильный синтаксис для объявления подкласса. Что-то не так с тем, что я написал?

Вы определили BMP или включили заголовок, который содержит его определение?

4 голосов
/ 31 января 2010

В языках C и C ++ термин адрес и термин указатель являются [почти] точными синонимами. На практическом, менее формальном языке термин address наиболее часто используется для обозначения rvalue значений указателя, в то время как термин pointer можно увидеть как используемый для обоих rvalue и lvalue значения указателя. В первом примере вы возвращаете значение r, поэтому термины «адрес» и «указатель» могут использоваться взаимозаменяемо. Вы возвращаете указатель на объект int. Вы возвращаете адрес объекта int. Оба означают одно и то же. Конечно, возвращать адрес локального объекта не имеет смысла, за исключением намеренной попытки вызвать неопределенное поведение.

Что касается второго вопроса, компилятор просто не знает, что такое BMP. Вы не объявили это. Более того, класс должен быть определен до того, как вы сможете использовать его в качестве базы в другом объявлении класса.

4 голосов
/ 31 января 2010

В первом случае указатель является адресом памяти, который указывает на некоторые данные, поэтому ваш синтаксис правильный. В этом случае, однако, вы возвращаете адрес локальной переменной, поэтому не определено, на что он будет указывать после завершения вызова функции.

Во втором случае компилятор жалуется, потому что не знает, что такое BMP. Возможно, вы забыли #include файл заголовка для BMP класса.

0 голосов
/ 07 декабря 2010

Думайте об этом так:

Если

char myChar;

объявляет переменную, которая хранит символ,

int* myPtr;

объявляет переменную, которая хранит адрес памяти.

Аналогично, если

char myCharFunction();

объявляет функцию, которая возвращает символ,

int* myPtrFunction();

объявляет функцию, которая возвращает адрес памяти.

Поэтому, поскольку подпись вашей функции int* FunctionB(int x), она верна при возврате адреса памяти.

Здесь важно понять, что int* означает «адрес памяти». И то, что мы называем «указателем», - это не что иное, как переменная , которая хранит в памяти адрес . Когда кто-то говорит, что указатель «указывает на адрес», все, что он имеет в виду, это то, что указатель содержит этот адрес в себе (так же, как переменная char будет содержать символ).

...