2009-12-31 147 views
-3

В C++ вы должны быть явным о многих вещах, например, об использовании delete. Это дает программисту больше возможностей, но это не всегда имеет смысл для меня. Например: инициализация массива символов в конструкторе. Почему не простые задачи, как они могут быть обработаны проще, чем таким образом:Почему требуется явное выражение на C++?

class x{ 
enum {Lim =20}; 
char a[Lim]; 

x(const char* s){ 
strncpy(a, s, Lim - 1); 
a[Lim - 1] = '\0'; 
} 
} 

В, C#, все, что вам нужно сделать, это:

class loai { 
public char[] a; 
public loai(char[] a) { 
    this.a = a; 
} 
} 

P.S: Извините за вчера. Я устал и не мог хорошо выразить свои идеи. Благодаря

+0

И вопрос? –

+0

Извините, теперь исправлено. –

+0

@ Лой Наджати: Я бы предложил положить? в конце вашего вопроса, так что более очевидно, что это вопрос. –

ответ

5

Вы можете инициализировать массив символов ....

char a[] = "hello"; 
+0

Почему голос? –

+0

Потому что это не то, о чем я говорил. –

+5

Ну, вы специально спросили, почему не удалось инициализировать массив символов ... Похоже, что это именно то, что вы просили. Я действительно понимаю, что вы искали более обобщенный ответ, но я думаю, что есть только конкретные ответы на ваши конкретные вопросы (какими бы они ни были). –

2

По большому счету, вы можете сделать простые задачи менее утомительным. Например, используйте интеллектуальные указатели, такие как auto_ptr, boost :: shared_ptr или scoped_ptr, и вам не придется вызывать удаление самостоятельно. Используйте такие функции, как std :: fill, укажите инициализатор для массивов или используйте другой тип (оговорки и примеры ниже и другие возможности, доступные в C++ 0x).

struct A { 
    char s[20]; 
    A() : s() { assert(s[0] == '\0'); /*always true*/ } 
    // you can only use the "default ctor", in this case char(), which is equal 
    // to '\0' 
}; 
// of course, if the item type of the array has a non-trivial ctor, it will 
// always be called for each item even if you leave the array member out of 
// the ctor init list 
struct B { 
    char s[20]; 
    B() { std::fill(s, s + boost::size(s), 'a'); s[boost::size(s)-1] = '\0'; } 
    // and if this is common, write your own function 
    // even make it a private static function if it's only used within this class 
    // (e.g. each ctor calls it, or several methods do) 
private: 
    template <int N> 
    static void fill_null_term(char (&a)[N], char value) { 
    // fill and null terminate 
    fill(a, a + N - 1, value); 
    a[N-1] = '\0'; 
    } 
    // notice two things: 
    // 1) certainly possible to pull this out of the class as required 
    // 2) don't hardcode constants, use the type system to your advantage 
    // (passing the array length) when possible 
}; 
struct C { 
    std::string s; 
    C() : s(19, 'a') {} 
    // mentioned last, but this would really be the first solution you use; 
    // refactoring to something else, such as A and B, as requirements change 
    // or are more clearly defined 
}; 
0

Поскольку вы добавили на вопрос, как C++, рассмотрим следующее:

class x 
{ 
public: 
    explicit x(const std::string &str) 
     : str_(str) 
    {} 

    explicit x(const char *str) 
     : str_(str ? str : "") 
    {} 

    ~x() {} 

private: 
    std::string str_; 
}; 

Не видеть, как C++ сделало бы меня слишком явным в любом случае. Да, std::string - это не совсем массив символов, но, спросите себя, вам действительно нужен ли он? Я бы не ожидал, что std::string будет выполнять значительно хуже, чем массив символов, вероятно, на 99% возможных вариантов использования. Итак, не делайте вашу жизнь сложной, используйте хорошие вещи, которые предоставляет вам C++, а не то, что осталось для совместимости с C, если вам не нужно и не знаете, что вы делаете.

EDIT: Ах, я вижу, то explicit ключевое слово добавляет «эксплицитность» на C++ :) забываю его на первом туре, набрав.

+0

На самом деле, я ожидал бы, что 'std :: string' будет работать лучше, чем массив символов, в большинстве случаев, поскольку' std :: string 'знают свою собственную длину, и поэтому их длина не должна быть пересчитана все время , (Конечно, 'char []' также может поставляться с длиной, но это утомительно и часто не выполняется). – Mankarse

0

Вот версия более простой C++, который выглядит почти так же, как ваш C образец #:

class loai { 
public: 
    std::vector<char> a; 
    loai(const std::vector<char>& a) : a(a) {} 
}; 

Конечно, вы можете сделать все очень сложное, используя неправильные типы данных, независимо от языка. В C++ простые массивы - очень простые типы, и поэтому во многих случаях более удобно использовать что-то вроде std::vector.

Смежные вопросы