Sẽ thay thế '::' bằng '. 'Tạo sự mơ hồ trong C ++?


95

Trong C ++, toán tử ::được sử dụng để truy cập các lớp, hàm và biến trong một không gian tên hoặc lớp.

Nếu đặc tả ngôn ngữ được sử dụng .thay vì ::trong các trường hợp đó giống như khi truy cập các biến / phương thức của đối tượng thì điều đó có thể gây ra sự mơ hồ có thể xảy ra không ::?

Vì C ++ không cho phép tên biến cũng là tên loại, tôi không thể nghĩ đến trường hợp điều đó có thể xảy ra.

Làm rõ: Tôi không hỏi tại sao ::được chọn hơn ., chỉ khi nó có thể làm việc quá?


Bình luận không dành cho thảo luận mở rộng; cuộc trò chuyện này đã được chuyển sang trò chuyện .
Samuel Liew

Câu trả lời:


124

Do các nỗ lực để làm cho C ++ hầu hết tương thích với mã C hiện có (cho phép xung đột tên giữa tên đối tượng và thẻ cấu trúc), C ++ cho phép xung đột tên giữa tên lớp và tên đối tượng.

Có nghĩa là:

struct data {
    static int member;
};

struct data2 {
    int member;
};

void f(data2& data) {
    data.member = data::member;
}

là mã hợp pháp.


11
Vì vậy, câu trả lời cho câu hỏi trong tiêu đề là Có, nó sẽ , phải không?
Enrico Maria De Angelis

2
@EnricoMariaDeAngelis nó không đơn giản. C ++ được phát triển như một ngôn ngữ hoàn toàn mới, như Java hay C #, sự mơ hồ có lẽ có thể tránh được . Nhưng C ++ được phát triển thành "C với các lớp" và đó là lý do tại sao không. "Có, nó sẽ " là một câu trả lời đúng, nhưng với một câu hỏi khác.
Bộ.

Chờ đợi, không phải là dòng phân công chỉ hiển thị rằng việc đưa .hoặc ::giữa cùng hai "chữ" có tác dụng khác nhau ( data.memberđề cập đến membertrong những datađối tượng của lớp data2, trong khi data::memberđề cập đến membercủa lớp data)?
Enrico Maria De Angelis

1
Vâng, nhưng đó không phải là điều mà các nhà thiết kế ngôn ngữ nên tự hào. Nó chỉ là một tạo tác của các quyết định tương thích.
Bộ.

Ok, tôi hiểu rằng C ++ ngày nay như thế nào và cho đến nay (cũng) phụ thuộc vào C là gì tại thời điểm C ++ phát triển từ nó. Nhưng nói về C ++ như hiện tại và bỏ qua một bên tại sao nó lại như vậy, sẽ có một sự mơ hồ nếu tất cả ::được đổi thành .. Theo cách bạn đã trả lời . Tôi chỉ đơn giản là không thể vi phạm vào bình luận đầu tiên của bạn. Có lẽ cấp độ của tôi làm cho nhận xét đó nhìn khói đối với tôi.
Enrico Maria De Angelis

37

Một ví dụ trong đó cả hai đều hợp lệ, nhưng tham chiếu đến các đối tượng khác nhau:

#include <iostream>

struct A {
    int i;
};

struct B {
    int i;
    A B;
};

int main() {
    B x {0, 1};
    std::cout << x.B.i << '\n';
    std::cout << x.B::i << '\n';
}

Xem trực tiếp trên coliru .


Và điều này không thể dễ dàng giải quyết với các quyết định thiết kế khác nhau!
dùng253751

7

Có sự khác biệt giữa a::ba.bnơi ::ngụ ý ađược sử dụng làm không gian tên, có nghĩa là đó là không gian tên hoặc tên kiểu chữ. Với điều kiện C ++ hỗ trợ kế thừa số nhiều không ảo và một biến có thể có cùng tên với một loại, điều này sẽ loại bỏ các cơ hội tham chiếu sai đối tượng. Nó là cần thiết cho siêu lập trình mẫu.

Một ví dụ khác sẽ là &B::foovs &B.footrong bối cảnh của lớp B.


2

Hãy mở rộng ví dụ @Ded repeatator:

#include <iostream>

struct A {
    int i;
};

struct B : public A {
    int i;
    A A;
};

int main() {
    B x {1, 2};
    std::cout << x.i << '\n';
    std::cout << x.B::i << '\n';  // The same as the line above.
    std::cout << x.A.i << '\n';
    std::cout << x.A::i << '\n';  // Not the same as the line above.
}

Trực tiếp trên Coliru Viewer

Không có khả năng phân biệt với sự trợ giúp của ::, thành viên nào chúng tôi muốn truy cập, không thể truy cập các thành viên được khai báo trong lớp cha có tên giống hệt nhau.


A A(tên biến cũng là tên loại) mặc dù không hợp lệ trong C ++, vì vậy ví dụ này hiện không hoạt động
Jimmy RT

1
@ JimmyR.T. Có ví dụ về cuộc sống làm việc trên Coliru Viewer. Xác nhận tuyên bố của bạn xin vui lòng với một đoạn từ tiêu chuẩn.
SM

Nếu người ta thêm viên kim cương thừa kế bị nguyền rủa ở đây với cùng một thứ ở phía bên kia, thì đó sẽ là đỉnh cao của việc đặt tên tâm thần phân liệt có thể có trong C ++
Swift - Friday Pie
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.