C # по умолчанию ключевое слово эквивалентно в C ++? - PullRequest
7 голосов
/ 12 сентября 2010

В C # я знаю, что вы можете использовать ключевое слово по умолчанию , чтобы назначать значения по умолчанию как 0 для типов значений и нуль для ссылочных типов, а для структурных типов назначаются соответствующие члены. Насколько мне известно, нет никаких значений по умолчанию в C ++. Какой подход вы бы использовали, чтобы получить ту же функциональность, что и ключевое слово по умолчанию для Generics при программировании на C ++?

Ответы [ 7 ]

11 голосов
/ 12 сентября 2010

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

template <typename T>
T get()
{
    return T(); // returns a value-initialized object of type T
}

Если тип не является конструируемым по умолчанию, как правило, вам нужно предоставить использование по умолчанию. Например,

template <typename T>
T get(const T& default_value = T())
{
    return default_value;
}

Эта функция может быть вызвана без аргумента, если тип является конструируемым по умолчанию. Для других типов вы можете указать возвращаемое значение.

2 голосов
/ 12 сентября 2010

C ++ не имеет ключевого слова default, поскольку не имеет различий между ссылочным типом и типом значения.В C ++ все типы - это то, что C # рассматривает как типы значений, и если они конструируются по умолчанию (как встроенные типы, структуры POD и типы классов с конструкторами по умолчанию), они инициализируются с использованием инициализации значения (синтаксис конструктора по умолчанию)Как показал Джеймс МакНеллис: (и беззастенчиво скопировал здесь)

template <typename T>
T get()
{
    return T(); // returns a value-initialized object of type T
}

, если T имеет конструктор по умолчанию, он вызывается.Если у него нет конструкторов, все инициализируется как ноль / ноль.

И если тип не является конструируемым по умолчанию, то там равно никакое значение по умолчанию, объект не может быть задан.

0 голосов
/ 12 сентября 2010

Это хороший вопрос.Плетора вариаций типа c ++ затрудняет написание безопасных шаблонов, подобных описанным ниже.

template <typename T> struct FrameworkTemplate {
 T mInstance;
};

Учтите, что теоретически пользователь может создать экземпляр шаблона вашего класса как

// assume A is a known default constructible type
FrameworkTemplate<A>
FrameworkTemplate<const A>
FrameworkTemplate<A const *>
FrameworkTemplate<A const &> // and so on

где последние три не являются конструктивными по умолчанию, хотя A может быть.Вот почему полезные универсальные типы, такие как any, nullable, lazy и т. Д., Хотя и просты и интуитивно понятны на первый взгляд, не так уж легко реализовать (безопасно) в c ++ ...

0 голосов
/ 12 сентября 2010

В C ++ вы обычно вызываете конструктор по умолчанию (конструктор, который можно вызывать без аргументов).Это работает и для примитивных типов (т. Е. int() равно 0, int*() - нулевой указатель и т. Д.).

Например, в функции шаблона вы должны написать что-то вроде:

template<typename T>
T foo()
{
    T x = T(); // See notes below about this.

    // Do other stuff.

    return x;
}

Обратите внимание, что одного T x; было бы достаточно для неявного вызова конструктора по умолчанию для не POD типов, но это не будет работать для примитивных скалярных типов (таких как int) где это было бы инициализировано для мусора.(T x() также не будет работать; , что будет интерпретироваться как объявление функции .)

0 голосов
/ 12 сентября 2010

Вот краткое изложение методов инициализации в C ++ 03.

Инициализация с нуля объекта типа T означает: - если T скалярного типа (3.9), объекту присваивается значение 0 (ноль) преобразуется в T;

— if T is a non-union class type, each nonstatic data member and each base-class subobject is zeroinitialized;

— if T is a union type, the object’s first named data member89) is zero-initialized;

— if T is an array type, each element is zero-initialized;

— if T is a reference type, no initialization is performed.

По умолчанию инициализировать объект типа T означает:

— if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

— if T is an array type, each element is default-initialized;

— otherwise, the object is zero-initialized.

Инициализация значения объекта типа T означает: >

— if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

— if T is a non-union class type without a user-declared constructor, then every non-static data member and base-class component of T is value-initialized;

— if T is an array type, then each element is value-initialized;

— otherwise, the object is zero-initialized

С этим пониманием

struct S{
   int x;
   S():x(1){}
};

S sg;                    // Every object of static storage duration is zero initialized at program startup before any other initialization takes place. So 'x' is initialized to 0, before the default constructor runs and sets 'x' to 1.

int main{
   int x = int();        // value initialization syntax, as per rules above is initialized to 0.

    S sl;                // default initialized
}
0 голосов
/ 12 сентября 2010

В C ++ назначение значения по умолчанию для переменной в глобальной области видимости или в функции так же просто, как:

int myint=2;
float* pfloat=NULL;

Для членов класса их нужно инициализировать в конструкторе класса:

class myclass {
private:
  int i;
public:
  myclass() {
    i = 4;
  }
};

Я не уверен насчет структур.

0 голосов
/ 12 сентября 2010

Используйте конструктор по умолчанию, он используется, даже если вы не указали () в конце:

#include <iostream>
class MyClass {
    public:
    int x;
    MyClass(){
        x = 5;
    }
};

int main(){
    MyClass y;
    std::cout << y.x;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...