2009-10-30 68 views
6

LƯU Ý: Tôi biết có nhiều câu hỏi đã nói về điều đó nhưng tôi vẫn là người mới bắt đầu và tôi không thể hiểu các ví dụ.const char * như một tham số hàm trong C++

Tôi có một nguyên mẫu chức năng mà đi như thế này:

int someFunction(const char * sm); 

Ở đây, như bạn đã biết, const char * có nghĩa là chức năng này có thể chấp nhận const hoặc con trỏ-to-char không const. Tôi đã thử nội dung nào đó giống như vậy trong phần thân hàm:

someMemberVar = sm; 

someMemberVar chỉ là một con trỏ tới char. Trình biên dịch cho tôi một lỗi nói với tôi: không thể chuyển đổi từ const char * sang char *.

Ở đây, tôi đã không vượt qua một hằng số, do đó, hoặc là sm hoặc someMemberVar không phải là hằng số. Vì vậy, những gì liên tục trình biên dịch đang nói về?

+1

Chính xác 'someMemberVar' được khai báo là gì và thông báo lỗi chính xác mà bạn nhận được (thông báo bạn cung cấp không có ý nghĩa gì, vì vậy tôi nghi ngờ có lỗi đánh máy). –

+0

Tôi đã sửa lỗi của mình. Nó tuyên bố như thế: char * someMemberVar; –

+1

@Alan anh ấy chủ yếu là chính xác. char * có thể được đúc một cách an toàn thành const char *, vì vậy bạn có thể chuyển một char * vào phương thức đó giống như bạn sẽ làm một const char *. Trình biên dịch sẽ chỉ làm diễn viên cho bạn. – Herms

Trả lời

10

tôi sẽ cố gắng đưa vào điều khoản đơn giản hơn những gì người khác đang nói:

Chức năng someFunction mất một chuỗi chỉ đọc (để đơn giản, mặc dù char * có thể được sử dụng trong nhiều lý do các trường hợp khác). Cho dù bạn chuyển một chuỗi chỉ đọc tới someFunction hay không, thông số được xử lý dưới dạng chỉ đọc bởi mã thực thi trong ngữ cảnh của hàm này. Trong hàm này do đó, trình biên dịch sẽ cố gắng ngăn không cho bạn ghi vào chuỗi này càng nhiều càng tốt. Một con trỏ không const là một cố gắng để bỏ qua thẻ chỉ đọc cho chuỗi và trình biên dịch, đúng và lớn tiếng thông báo cho bạn về việc bỏ qua đó cho hệ thống kiểu của nó;)

Sự khác biệt giữa: int someFunction (const char * sm) const {...} và điều này: int someFunction (const char * sm) {...}

Đầu tiên là hàm có tham số chỉ đọc. Số thứ hai const được viết sau khi đóng ngoặc đơn chỉ hợp lệ cho các hàm thành viên. Nó không chỉ mất một tham số chỉ đọc, mà cả các gurantees để không thay đổi trạng thái của đối tượng. Điều này thường được gọi là const mức thiết kế.

+0

Tốt thôi. Sự khác biệt giữa: int someFunction (const char * sm) const {...} và điều này: int someFunction (const char * sm) {...} –

+0

int someFunction (const char * sm) const {. ..} const ở đây có nghĩa là tôi sẽ không thay đổi bất kỳ dữ liệu nào ở đây cả, hoặc nó đề cập đến tham số? –

+0

Xem câu trả lời cập nhật của tôi. – dirkgently

10

Nó không phải là hoàn toàn rõ ràng từ câu hỏi của bạn, và tôi nghi ngờ nội dung của lỗi mà bạn đưa ra là thực sự sai, và thực sự đọc:

không thể chuyển đổi từ const char* để char*

Vì bạn nói rằng

someMemberVar chỉ là một con trỏ tới char.

Điều này có ý nghĩa. Hãy nhớ rằng const char* thực sự giống như char const* - tức là, nó là một con trỏ tới một ký tự const, không phải là con trỏ const đến char! Và bạn không thể chuyển đổi con trỏ thành T const thành con trỏ đến T, vì điều đó phá vỡ sự an toàn về loại. Hãy xem xét:

const char* a = "abc"; 
char* b = a; // what you're trying to do 
b[0] = 'x'; // if you could do it, you could change const data without casts 
+0

Cảm ơn nó thực sự đã giúp. –

1

Nếu bạn chuyển con trỏ không đến someFunction, nó sẽ tự động được chuyển thành con trỏ const. Vì vậy, bạn không thể chỉ định sm cho someMemberVar vì điều đó sẽ vi phạm độ mờ của sm. Bạn có thể khai báo someMemberVarconst char* và mã của bạn sẽ hoạt động, tuy nhiên, bạn không thể sửa đổi những gì nó trỏ đến.

+0

const char * sm có nghĩa là tôi có thể vượt qua một const hoặc không const, vậy tại sao C++ tự động chuyển đổi nó? Điều đó không có ý nghĩa với tôi. –

+1

"const char * sm" có nghĩa là "pointer to const char". Không có gì khác. Đó là những gì sm sẽ được trong someFunction. Bạn có thể chuyển một "char *" đến someFunction vì việc chuyển đổi từ không const thành const được cho phép. Loại bỏ constness không được phép, đó là những gì bạn đang cố gắng làm khi bạn gán sm cho someMemberVar. – jamessan

+1

Bên trong hàm, con trỏ sẽ được chuyển đổi vì bạn muốn nó nằm trong hàm đó - bạn đã khai báo nó theo cách đó. Đó là một phần của hợp đồng mà chức năng tạo ra với người gọi của nó. Nếu hàm không muốn bảo đảm rằng bộ nhớ được chỉ bởi sm không thay đổi thì đừng tạo tham số const char *. –

0

const char * sm là một con trỏ trỏ đến một ký tự không đổi (hoặc mảng). Khi bạn cố gắng chỉ định, someMemberVar, một con trỏ tới char, bạn đang cố trỏ nó đến một tập hợp hằng số ký tự. Đây là nguyên nhân gây ra lỗi.

3

const char* là một con trỏ để liên tục char:


const char* ptr0; // ptr0 is mutable, *ptr0 is const 
char* const ptr1; // ptr1 is const, *ptr1 is mutable 
0

Trong ví dụ sm của bạn là const char * để someFunction có một hợp đồng với nó là người gọi rằng nó sẽ không sửa đổi các bộ nhớ rằng điểm sm để.

Nhưng nếu bạn gán sm cho một sốMemberVar và someMemberVar không phải là const char *, bạn sẽ có thể sửa đổi bộ nhớ mà sm trỏ tới qua someMemberVar và trình biên dịch không cho phép bạn làm điều đó.

1

Trong một bình luận từ một trong những câu trả lời khác bạn nói:

const char * sm có nghĩa là tôi có thể vượt qua một const hoặc không const, vậy tại sao C++ chuyển đổi nó tự động? Điều đó không có ý nghĩa với tôi.

Giữa câu hỏi ban đầu của bạn và nhận xét đó Tôi nghĩ bạn hiểu sai về cách trình biên dịch xử lý các loại.

Bạn đúng rằng không phải là char * có thể được truyền an toàn đến const char *. Tuy nhiên, phương pháp của bạn rõ ràng là lấy const char *. Vì vậy, trong khi bạn có thể vượt qua một char * vào hàm, trình biên dịch sẽ tự động bỏ qua đối số khi thực hiện cuộc gọi hàm. Mã thực tế trong hàm không biết liệu đối số ban đầu có phải là const hay không. Trình biên dịch phải đi theo khai báo thực tế của biến mà bạn đang sử dụng, không phải một số biến trước đó có cùng giá trị.

Nếu bạn muốn có thể xử lý các biến khác nhau char * khác nhau (chỉ định cho chúng) thì bạn sẽ cần phải xác định hàm không có biến số char *.

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