Значение по умолчанию указателя функции в C++
каково значение по умолчанию указателя функции в C++? (Очевидно, этого не может быть!--1-->, Так что это?)
Как эта программа должна себя вести и почему?
struct S { void (*f)(); };
int main()
{
S s = S();
s.f(); // What is the value of s.f?
}
5 ответов
в вашем случае объект s
инициализируется нулем, что означает, что указатель функции NULL
.
struct S { void (*f)(); };
int main()
{
S s = S();
if ( s.f == NULL)
std::cout << "s.f is NULL" << std::endl;
}
выход:
s.f is NULL
первый любой указатель может быть null. Это единственная универсальная истина о указателях. Тем не менее, ваш будет быть null, но не обязательно по причинам, которые вы, возможно, думаете;
C++11 § 8.5, p10
объект, инициализатором которого является пустой набор скобок, т. е. (), должно быть значение инициализации.
это важно, потому что ваша декларация включает это :
S s = S();
по определению инициализация значением:
C++11 § 8.5, p7
значение-инициализировать объект типа T означает:
Если T является (возможно в CV-квалифицированный) тип класса (п. 9), предоставленный пользователем конструктор (12.1), то конструктор по умолчанию для T называется (и инициализация плохо сформированной, если T имеет никакого доступного по умолчанию конструктор);
Если T является (возможно, CV-квалифицированным) типом класса non-union без предоставленного пользователем конструктора, то объект ноль-инициализировать и, если конструктор по умолчанию t неявно объявлен нетривиальным, этот конструктор вызывается.
Если T-тип массива, то каждый элемент инициализируется значением;
в противном случае, объект ноль-инициализировать.
что подводит нас к тому, что означает, что ваш тип объекта должен быть инициализирован нулем:
C++11 § 8.5, p5
to zero-инициализировать объект или ссылку типа T означает:
Если T-скалярный тип (3.9), то объекту присваивается значение 0 (ноль), взятое как интегральное постоянное выражение, преобразованное в T (103)
Если T является (возможно, CV-квалифицированным) типом класса non-union,каждый нестатический элемент данных и каждый субобъект базового класса инициализируется нулем и обивка инициализируется нулевым значением бита;
Если T является (возможно, CV-квалифицированным) типом объединения, Первый нестатический именованный элемент данных объекта инициализируется нулем, а заполнение инициализируется нулевыми битами;
Если T является массивом тип, каждый элемент инициализирован нулем;
Если T является ссылочным типом, то инициализация не выполняется.
103) как указано в 4.10, преобразование интегрального постоянного выражения, значение которого равно 0, в тип указателя приводит к нулевой указатель, то значение.
последнее является причиной того, что указатель равен null. Это будет не гарантируйте-так стандартом, который дали такой же код, но изменяющ заявление s
для этого:
S s;
учитывая объявление, подобное приведенному выше, через стандарт берется другой путь:
C++11 § 8.5, p11
Если для объекта не указан инициализатор, то объектом является по умолчанию-инициализировать; если инициализация не выполняется, объект с автоматической или динамической длительностью хранения имеет неопределенное значение. [ Примечание: объекты со статической или потоковой длительностью хранения инициализируются нулем, см. 3.6.2.
какой тогда напрашивается последний вопрос, Что такое инициализация по умолчанию:
C++11 § 8.5, p6
по умолчанию-инициализировать объект типа T означает:
Если T является (возможно в CV-квалифицированный) тип класса (п. 9), конструктор по умолчанию для T называется (и инициализация плохо сформированной, если T имеет никакого доступного по умолчанию конструктор);
Если T-тип массива, то каждый элемент инициализируется по умолчанию;
в противном случае инициализация не выполняется.
указатель функции может быть NULL, и вы можете назначить ему NULL. Посмотрите здесь например:
#include <iostream>
using namespace std;
struct S { void (*f)(); };
int main()
{
S s = S();
s.f = NULL;
return 0;
}
Я считаю, что вы называете конструктор структуры (с ()
), f будет NULL.
указатель функции может быть нулевым, таким образом, вы можете указать, что они ни на что не указывают!
В C++ (и C) указатели (независимо от типа) не имеют значения по умолчанию per se; они берут то, что когда-нибудь случается в памяти в то время. Однако у них есть инициализированное значение по умолчанию NULL
.
Инициализация По Умолчанию
когда вы явно не определяете конструктор, C++ вызовет инициализатор по умолчанию для каждой переменной-члена, который инициализирует указатели на 0
. Однако, если вы определяете конструктор, но не устанавливаете значение для указателя не имеет значения по умолчанию. Поведение одинаково для целых чисел, поплавков и двойников.
в сторону
int main()
{
S s = S();
s.f(); // <-- This is calling `f`, not getting the pointer value.
}