2013-04-09 52 views
7

Tôi có một chút vấn đề với hàm tạo của mình. Trong tập tin tiêu đề của tôi, tôi tuyên bố:Lỗi C++: Các loại không tương thích khi gán ‘char *’ cho ‘char [2]

char short_name_[2]; 
  • và các biến khác

Trong constructor của tôi:

Territory(std::string name, char short_name[2], Player* owner, char units); 
void setShortName(char* short_name); 
inline const char (&getShortName() const)[2] { return short_name_; } 

Trong tập tin cpp của tôi:

Territory::Territory(std::string name, char short_name[2], Player* owner, 
        char units) : name_(name), short_name_(short_name), 
        owner_(owner), units_(units) 
{ } 

lỗi của tôi:

Territory.cpp: In constructor ‘Territory::Territory(std::string, char*, Player*, char)’: Territory.cpp:15:33: error: incompatible types in assignment of ‘char*’ to ‘char [2]’

Tôi đã tìm ra rằng char[2] <=> char* nhưng tôi không chắc chắn làm thế nào để xử lý này về constructor của tôi và nhận/setters.

+1

'Tôi đã tìm ra rằng char [2] <=> char *' không thực sự. – Rapptz

+0

nhưng tôi nghĩ cho trình biên dịch C++ là char [2] tương đương với char *?! tôi thực sự không có ý tưởng làm thế nào để init constructor này và getters corretly ... – vicR

+1

Mảng và con trỏ là * rất * những thứ khác nhau. Đọc phần 6 của [comp.lang.c FAQ] (http://www.c-faq.com/); các quy tắc trong lĩnh vực này về cơ bản là giống nhau cho C và C++. –

Trả lời

12

Mảng thô trong C++ là loại gây phiền nhiễu và đầy nguy hiểm. Đây là lý do tại sao trừ khi bạn có lý do chính đáng để bạn nên sử dụng std::vector hoặc std::array.

Trước hết, như những người khác đã nói, char[2] không giống như char* hoặc ít nhất là không thường xuyên. char[2] là mảng có kích thước 2 là charchar* là con trỏ đến số char. Chúng thường bị nhầm lẫn bởi vì mảng sẽ phân rã thành con trỏ đến phần tử đầu tiên bất cứ khi nào chúng cần. Vì vậy, công trình này:

char foo[2]; 
char* bar = foo; 

Nhưng ngược lại không:

const char* bar = "hello"; 
const char foo[6] = bar; // ERROR 

Thêm vào sự nhầm lẫn, khi tuyên bố thông số chức năng, char[] tương đương với char*. Vì vậy, trong hàm tạo của bạn, tham số char short_name[2] thực sự là char* short_name.

Một quirk khác của mảng là chúng không thể được sao chép như các loại khác (đây là một giải thích cho lý do tại sao mảng trong tham số hàm được coi là con trỏ).Vì vậy, ví dụ tôi có thể không làm điều gì đó như thế này:

char foo[2] = {'a', 'b'}; 
char bar[2] = foo; 

Thay vào đó tôi phải lặp qua các yếu tố của foo và sao chép chúng vào bar, hoặc sử dụng một số chức năng mà làm thế đối với tôi như std::copy:

char foo[2] = {'a', 'b'}; 
char bar[2]; 
// std::begin and std::end are only available in C++11 
std::copy(std::begin(foo), std::end(foo), std::begin(bar)); 

Vì vậy, trong constructor của bạn, bạn phải tự sao chép các yếu tố của short_name vào short_name_:

Territory::Territory(std::string name, char* short_name, Player* owner, 
        char units) : name_(name), owner_(owner), units_(units) 
{ 
    // Note that std::begin and std::end can *not* be used on pointers. 
    std::copy(short_name, short_name + 2, std::begin(short_name)); 
} 

Như bạn có thể thấy điều này rất khó chịu, vì vậy, trừ khi bạn có lý do chính đáng, bạn chỉ nên sử dụng std::vector thay vì mảng thô (hoặc trong trường hợp này có thể là std::string).

2

Khi một hàm muốn một mảng làm đối số, nó sẽ lấy một con trỏ tới phần tử đầu tiên của một mảng thay thế. Con trỏ này không thể được sử dụng để khởi tạo một mảng, bởi vì nó là một con trỏ, không phải là một mảng.

Bạn có thể viết các chức năng chấp nhận tài liệu tham khảo cho các mảng như các đối số:

void i_dont_accept_pointers(const char (array&)[2]) {} 

Vấn đề ở đây là, rằng tài liệu tham khảo mảng này không thể được sử dụng để khởi mảng khác.

class Foo { 
    char vars[2]; 
    Foo(const char (args&)[2]) 
    : vars(args) // This will not work 
    {} 
}; 

C++ 11 giới thiệu std::array để loại bỏ vấn đề này và các vấn đề khác của mảng. Trong các phiên bản cũ hơn, bạn sẽ phải lặp qua các phần tử mảng và sao chép chúng riêng lẻ hoặc sử dụng std::copy.

Các vấn đề liên quan