2010-09-12 27 views
7

En C# Sé que puede usar default keyword para asignar valores predeterminados como 0 a tipos de valores y nulos a tipos de referencia y para tipos de estructuras, los miembros individuales se asignan en consecuencia. Que yo sepa, no hay valores predeterminados en C++. ¿Qué enfoque tomaría para obtener la misma funcionalidad que la palabra clave predeterminada para Generics mientras programa en C++?C# 's palabra clave predeterminada equivalente en C++?

Respuesta

11

Suponiendo que el tipo es predecible, se puede usar la inicialización de valores. Por ejemplo,

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

Si el tipo no es predecible, normalmente debe proporcionar un predeterminado para usar. Por ejemplo,

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

Esta función se puede invocar sin argumentos si el tipo es predecible. Para otros tipos, puede proporcionar un valor que se devolverá.

0

Utilice un constructor por defecto, se utiliza incluso si se deja fuera de la () al final:

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

int main(){ 
    MyClass y; 
    std::cout << y.x; 
} 
0

En C++, la asignación de un valor predeterminado a una variable de alcance global o en una función es tan simple como :

int myint=2; 
float* pfloat=NULL; 

para miembros de la clase, es necesario inicializar éstos en el constructor de la clase:

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

No estoy seguro acerca de las estructuras.

+2

estructuras y las clases son exactamente los mismos en C++, excepto por su visibilidad predeterminada. –

2

C++ no tiene la palabra clave default, porque no tiene la distinción entre los tipos de referencia y de valor. En C++, todos los tipos son lo que C# consideraría tipos de valores, y si son predecibles (como tipos incorporados, estructuras POD y tipos de clases con constructores por defecto), se inicializan utilizando la inicialización del valor (la sintaxis del constructor por defecto) , como James McNellis mostró: (y descaradamente copiado aquí)

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

si T tiene un constructor por defecto, se invoca. Si no tiene constructores, todo se inicializa a cero/nulo.

Y si el tipo no es construible por defecto, es no hay valor predeterminado para el objeto.

0

Aquí hay un breve resumen de las técnicas de inicialización en C++ 03.

Para inicializar a cero un objeto de tipo T significa: - si T es un tipo escalar (3.9), el objeto se establece en el valor de 0 (cero) convertido a 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. 

Para default-inicializar un objeto de tipo T significa:

— 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. 

Para valor a inicializar un objeto de tipo T significa: >

— 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 

Con ese entendimiento

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

En C++, habitualmente se invoca el constructor por defecto (el constructor que se puede llamar sin argumentos). Esto también funciona para tipos primitivos (es decir, int() es 0, int*() es el puntero nulo, etc.).

Por ejemplo, en su función de plantilla, que iba a escribir algo como:

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

    // Do other stuff. 

    return x; 
} 

Tenga en cuenta que T x; por sí sola sería suficiente para invocar implícitamente un constructor por defecto para los tipos POD no, pero que wouldn' t funciona para los tipos escalares primitivos (como int) donde se inicializaría a la basura. (T x() tampoco funcionaría; that would be interpreted as a function declaration.)

0

Esta es una buena pregunta. La pletora de las variaciones de tipo C++ hace que escribir plantillas seguras del tipo que está debajo de un dolor.

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

consideran que, en teoría, el usuario podría crear una instancia de la plantilla de clase como

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

donde los tres últimos no están por defecto construible, aunque podría ser una. Es por eso que los tipos genéricos útiles como any, nullable, lazy y así sucesivamente, aunque es simple e intuitiva a primera vista, no son triviales para poner en práctica (con seguridad) en C++ ...