Trong hiệu quả hơn C++, một điểm thú vị được đưa ra là sự pha trộn của mảng và đa hình là một ý tưởng tồi. Đối với ví dụ:Cảnh báo biên dịch cho mảng hỗn hợp và đa hình
class Base {
public:
Base(int y) : a(y) {}
int a;
};
class D : public Base {
public:
D(int w, int y) : Base(y), c(w) {}
int c;
};
std::ostream& operator<<(std::ostream& os, const Base &obj)
{
os << obj.a << std::endl;
return os;
}
// This function will work perfectly well if i pass in a `Base` array,
// but if i pass in `D` array we are going to run into some problems.
// Namely that `arr[i+1] = &arr[i] + sizeof(Base)` will not progress
// the array correctly for a `D` array.
void printArray(const Base arr[]) {
for (int i = 0; i < 5; ++i) {
std::cout << arr[i];
}
}
int main() {
D arr[5] = { D(0, 10), D(1, 11), D(2, 12), D(3, 13), D(4, 14)};
printArray(arr); // This compiles without complaint! I understand that the
// conversion is legal, but it seems like a warning
// about this would be a good idea.
}
Lưu ý: Tôi biết đây là thiết kế xấu nhưng là để minh họa cho một điểm. Vấn đề ở đây là khi trộn hai cái này theo cách tôi có ở trên, khi chúng ta lặp qua mảng để in, chúng ta sẽ không tiến hành phần tử của mảng theo đúng số lượng (tức là chúng ta di chuyển bởi sizeof(Base)
thay vì sizeof(D)
). Điều này dẫn đến kết quả:
10
0
11
1
12
(Và tôi đang đoán rằng gọi operator<<
như thế này có lẽ là UB).
Khi biên dịch với g++ -std=c++1y -Wall -Weffc++ -pedantic main.cpp
Tôi không nhận được cảnh báo hoặc lỗi.
- Có cờ trình biên dịch mà tôi có thể bật cho biết cảnh báo trong trường hợp này không?
- Nếu không, tại sao không?
Vâng, câu trả lời cho '2)' là "cảnh báo" không bắt buộc đối với trình biên dịch để triển khai. Bạn có thể yêu cầu những người triển khai g ++ thêm một cảnh báo như vậy (nếu nó không tồn tại), nhưng chúng không bị ép buộc làm như vậy theo bất kỳ tiêu chuẩn nào. – PaulMcKenzie
@PaulMcKenzie, đúng, nhưng GCC đi trên và xa hơn với cảnh báo của họ, tôi tự hỏi nếu có một khó khăn kỹ thuật trong việc phát hiện này? –
Bạn phải yêu cầu các kỹ sư tổng hợp trình biên dịch. Có câu trả lời có thể là bất cứ nơi nào từ "đó là một ý tưởng tốt" để "chúng tôi không có thời gian" để "nó đã tồn tại". – PaulMcKenzie