2010-03-09 48 views
7

tại sao tôi nhận được một lỗi discard qualifiers:g ++: const loại bỏ vòng loại

customExc.cpp: In member function ‘virtual const char* CustomException::what() const’: 
customExc.cpp: error: passing ‘const CustomException’ as ‘this’ argument of ‘char customException::code()’ discards qualifiers 

trên mã ví dụ sau

#include <iostream> 


class CustomException: public std::exception { 

public: 

    virtual const char* what() const throw() { 
     static std::string msg; 
     msg = "Error: "; 
     msg += code(); // <---------- this is the line with the compile error 
     return msg.c_str(); 
    } 

    char code() { return 'F'; } 
}; 

Tôi đã tìm kiếm xung quanh trên SOF trước về các vấn đề simular.

Tôi đã thêm const vào mọi nơi có thể.

hãy soi sáng cho tôi - Tôi không nắm được vấn đề ...

EDIT: đây là các bước để tái tạo trên Ubuntu-Carmic-32bit (g ++ v4.4.1)

  1. tiết kiệm ví dụ như customExc.cpp
  2. loại make customExc.o

EDIT: Lỗi liên quan đến CustomException. Lớp học Foo không liên quan gì đến nó. Vì vậy, tôi đã xóa nó.

+2

Nhân tiện, bạn không nên trả về 'msg.c_str()', vì 'msg' bị hủy ngay sau khi' what() 'trả về - có nghĩa là con trỏ sẽ không hợp lệ nữa khi người dùng đọc nó . Bạn có thể muốn xem xét xây dựng nó vào thời gian xây dựng và lưu trữ nó như là một thành viên trong lớp. –

+0

@Raphael: Tôi biết. Tôi chỉ muốn giữ ví dụ đơn giản nhất có thể.Và - vì giá trị trả về của 'what()' là 'const' - nó không phải là một vấn đề trong thực tế. –

+1

Tôi không thấy giá trị trả về 'what()' là 'const' phải làm gì với sự an toàn của việc trả về' msg.c_str() '... nó được bảo đảm trỏ đến bộ nhớ không tồn tại, đó là hành vi không xác định. đừng làm thế! – rmeador

Trả lời

14

CustomException::what gọi CustomException::code. CustomException::what là phương pháp const, được ký hiệu bởi const sauwhat(). Vì nó là một phương thức const, nó không thể làm bất cứ điều gì có thể sửa đổi chính nó. CustomException::code không phải là phương pháp const, nghĩa là không hứa sẽ không tự sửa đổi. Vì vậy, CustomException::what không thể gọi CustomException::code.

Lưu ý rằng các phương thức const không nhất thiết liên quan đến các cá thể const. Foo::bar có thể khai báo biến số exc của nó như các phương thức không const và gọi const như CustomException::what; điều này đơn giản có nghĩa là CustomException::what hứa hẹn sẽ không sửa đổi exc, nhưng mã khác có thể.

Câu hỏi thường gặp C++ có thêm thông tin về số const methods.

+0

@Josh: Bây giờ tôi đã nhận nó - và cuối cùng tôi đã chấp nhận câu trả lời của bạn vì' ... what() hứa hẹn sẽ không sửa đổi exc ... ' –

3

what() của bạn là hàm thành viên const, nhưng code() thì không.

Chỉ cần thay đổi code() thành code() const.

4
int code() const { return 42; } 
+1

Cảm ơn điều này đã giúp tôi. Tôi đã đặt const trước tên hàm không sau. –

3

Chức năng thành viên code() không được khai báo const. Việc gọi các hàm thành viên không phải từ các hàm thành viên const (what() trong trường hợp này) là bất hợp pháp.

Tạo thành viên code() const.

+1

đó là một thông báo lỗi khá mờ đục ... – rmeador

+0

@meador: ** ** ** trên một phương thức có nghĩa là, ** này ** sẽ là một con trỏ-để-const trong phương pháp này. Nếu bạn nhận thức được điều đó, thông báo lỗi có ý nghĩa hoàn hảo: khi bạn cố gắng gọi 'code()' từ 'what()', bạn đang cố chuyển đổi '(const CustomException *) this' thành' (CustomException *) này', do đó loại bỏ cv vòng loại (s) (** const **) – UncleBens

+0

Tôi nghĩ rằng @rmeador làm cho một điểm tốt. Tôi đã quen với thông báo lỗi đó, nhưng nó có thể dễ dàng nói "' Không thể gọi 'char customException :: code()' từ 'virtual const char * CustomException :: what() const' vì 'char customException :: code() 'không phải là hàm thành viên const.' " – Ben

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