2014-09-10 22 views
6

Tôi mới sử dụng C++ và tôi đang cố gắng tạo một ngoại lệ tùy chỉnh để nhận thông báo trong ctor của nó.Cách tạo đúng ngoại lệ tùy chỉnh bằng tin nhắn?

Những gì tôi có ngay bây giờ đây là:

class LevelLoadException : public std::exception 
{ 
public: 
    LevelLoadException(std::string msg) : m_message(msg) { } 
    const char * what() const throw() 
    { 
     return m_message.c_str(); 
    } 
private: 
    std::string m_message; 
}; 

Trong mã gọi điện thoại của tôi, tôi có điều này như một phần của báo cáo chuyển đổi (c là một char, hay cụ thể hơn, c = line[x]; nơi x là một intlinestd::string);

default: 
    throw LevelLoadException("Invalid Character in Level: " + c); 

Vấn đề là ngoại lệ của tôi nhận được chuỗi hoàn toàn không liên quan (đó là một phần của cùng phương thức ném: throw std::exception("There is more than 1 player start in the level.")).

Tôi đã loại trừ lỗi logic - chương trình của tôi đạt đến dòng nơi ngoại lệ chính xác với chuỗi chính xác được ném. Vì vậy, tôi khá chắc chắn đó là một vấn đề quản lý thời gian/bộ nhớ.

Theo tôi, C++ là bản sao theo giá trị theo mặc định. Vì vậy, tôi nghĩ rằng việc gọi ctor của LevelLoadException sẽ ngay lập tức sao chép chuỗi. Nhưng có vẻ như có một số công cụ con trỏ đang diễn ra, vì chuỗi mà tôi đang xây dựng có vẻ giống như một chuỗi C (const char*).

tôi nhìn vào lớp std::exception, và điều này cần một const char* const& như tin nhắn và sau đó thực hiện một số C-like strcopy/malloc dưới mui xe (MSVC/Visual Studio 2012 Update 4).

Tôi không chắc chắn trăm phần trăm những gì tôi thực sự cần. Tôi nghĩ những gì tôi muốn là một chuỗi được xây dựng trong người gọi, sau đó di chuyển/sao chép vào Ngoại lệ (hiện đang sở hữu một bản sao của chuỗi chỉ thuộc sở hữu của ngoại lệ) và sau đó người gọi bị hủy khi nó hết phạm vi.

Ai đó có thể cho tôi a pointer những gì tôi nên làm khác đi để thực hiện việc này đúng cách không?

+0

Và bạn bắt một ngoại lệ std? – Christophe

+0

@Christophe Không, tôi có 'catch (LevelLoadException & e)' trong người tiêu dùng. –

+5

Bạn nên lấy từ 'std :: runtime_error' thay vì' std :: exception'. Sau đó, lớp học của bạn có thể được giảm xuống thành [một vài dòng] (http://coliru.stacked-crooked.com/a/9666bd1e13f8f25c). – Praetorian

Trả lời

12

"Invalid Character in Level: " + c không làm những gì bạn nghĩ. Nó có nghĩa là "một con trỏ char* được bù đắp bởi N byte từ đầu chuỗi chữ", trong đó N là mã ASCII của ký tự được lưu trữ trong c. Cơ hội có nghĩa đen cao thực sự ngắn hơn N ký tự, trong trường hợp này chương trình này chứa tràn bộ đệm và thể hiện hành vi không xác định.

Làm cho nó

throw LevelLoadException(std::string("Invalid Character in Level: ") + c); 
+1

Ah, cảm ơn. Vì vậy, '" string "' trả về một 'char *' (cho C ngược lại) và sau đó tôi đang làm toán con trỏ (char c trở thành giá trị số 99)? Việc chuyển chuỗi '" thành chuỗi C++ sử dụng toán tử '+' của 'std :: string'? –

+0

@Praetorian: Ah, phải. Tôi sẽ sửa lỗi, mặc dù về cơ bản nó không thay đổi câu trả lời. –

+0

@MichaelStum: Bạn nhận được nó (modulo '99' thực sự là mã ASCII của bất kỳ ký tự nào xảy ra được lưu trữ trong biến' c'; đó là lỗi của tôi, xin lỗi vì nhầm lẫn). –

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