Làm thế nào tôi có thể truyền một đối tượng làm tham số cho hàm?


8

Tôi đang làm một trò chơi nhỏ, và muốn lưu trữ điểm số cao. Tôi đã tạo một lớp Highscore ở đầu tệp phác thảo, như thế này:

class Highscore {
public:
  String name;
  int score;

  String toString() {
    return this->name + " - " + (String)score;
  }

  Highscore(String name, int score) {
    this->name = name;
    this->score = score;
  }
};

setup() { // etc

Hiện nay. Gần cuối bản phác thảo, tôi có một hàm tôi muốn lấy một đối tượng Highscore làm tham số, nhưng trình biên dịch sẽ không cho phép tôi. Thí dụ:

void writeHighscore(Highscore hs) {
  File f = SD.open("high.txt", FILE_WRITE);
  // Do stuff

Lỗi biên dịch như sau:

sketch.ino: 19: 21: error: biến hoặc trường 'writeHighscore' đã khai báo void
sketch.ino: 19: 21: error: 'Highscore' không được khai báo trong phạm vi này
sketch.ino: Trong hàm 'void setup ()':
sketch.ino: 64: 20: lỗi: 'writeHighscore' không được khai báo trong phạm vi này

Sau khi thay đổi loại tham số thành Chuỗi, int hoặc bất cứ điều gì, tất cả các lỗi sẽ biến mất. Tôi có thể tạo các đối tượng Highscore bên trong writeHighscore()hàm, nhưng làm cách nào tôi có thể truyền các đối tượng cho nó?

Chỉnh sửa 1 - Tạo đối tượng

Highscore hs = Highscore("John", 975);
Serial.println(hs.toString()); // Prints "John - 975" as expected
writeHighscore(hs); // Error

bạn có thể vui lòng gửi mã nơi bạn tạo đối tượng Highscore không?
Omer

Bao gồm mã tạo đối tượng.
kstallah

2
Tôi nghĩ rằng vấn đề là một số thiếu khung hoặc như vậy. Vì không có mã đầy đủ, tôi có thể đoán và xem: 1) setup () nên void setup () . Nhưng nó sẽ tạo ra cảnh báo / lỗi C ++. 2) Truyền tham số lớp bắt buộc sao chép đối tượng khi thủ tục được gọi. gcc cũng sẽ tạo cảnh báo nếu thiếu hàm tạo sao chép. Sử dụng: void writeHighscore (Highscore & hs) hoặc void writeHighscore (Highscore * hs) Sao chép snipet có thể biên dịch trong bài viết của bạn.
TMa

Giống như đã nêu trong câu hỏi ban đầu, bằng cách thay đổi tham số Highscore bằng, giả sử, Chuỗi hoặc int, các lỗi sẽ biến mất, không có dấu ngoặc bị thiếu. Tôi cũng đã thử &hscách tiếp cận trước khi viết bài, cũng như chuyển con trỏ writeHighscore(&hs)-> void writeHighscore(Highscore *hs)nhưng không có kết quả.
kstallah

Vui lòng gửi mã nguồn đầy đủ, nếu không các số dòng trong lỗi biên dịch là vô nghĩa.
jfpoilpret

Câu trả lời:


6

Bạn đang làm mọi thứ đúng, nhưng bạn cần di chuyển lớp bên ngoài tệp .ino của bạn để làm việc này. Tôi không chắc tại sao IDE arduino khiến bạn làm điều này (xem chỉnh sửa), nhưng đó là thứ tôi đã gặp phải trước đây.

Tôi vừa thử nghiệm điều này, và di chuyển khai báo lớp bên ngoài ino và vào một tệp tiêu đề trong thư mục dự án làm cho nó biên dịch chính xác. Chỉ cần nhớ bao gồm tiêu đề bạn thực hiện trong ino và #include "Arduino.h"trong tiêu đề để có quyền truy cập lại vào "Chuỗi".

Về mặt kỹ thuật, chỉ có một tuyên bố chuyển tiếp của lớp cần phải ở trong một tệp khác.

Biên tập:

Tôi tương đối chắc chắn những gì đang xảy ra là IDE đang tạo ra các khai báo chuyển tiếp cho tất cả các hàm của bạn chứ không phải lớp, được đặt trước định nghĩa lớp của bạn. Điều này có nghĩa là việc phá vỡ chức năng regex mà IDE sử dụng với một "throw ()" giả sẽ khắc phục vấn đề của bạn. ví dụ:

void writeHighscore(Highscore hs) throw() { ...

chỉ nên làm việc tốt thôi (nó làm việc cho tôi)


2

Đây là một ví dụ cổ điển về IDE "giúp đỡ" bạn bằng cách tạo các nguyên mẫu hàm và không làm tốt lắm. Mã ví dụ để sao chép:

class Highscore {
public:
  String name;
  int score;
  String toString() {
    return this->name + " - " + (String)score;
  }

  Highscore(String name, int score) {
    this->name = name;
    this->score = score;
  }
};

void setup () { }
void loop () { }

void writeHighscore(Highscore hs) 
{
// do stuff
}

Điều này đưa ra lỗi:

sketch_jul06b:4: error: variable or field writeHighscore declared void
sketch_jul06b:4: error: Highscore was not declared in this scope

Nếu bạn nhìn vào đầu ra của bộ tiền xử lý IDE (bạn có thể làm điều này bằng cách bật trình biên dịch dài dòng và tìm ra tên của tệp mà nó thực sự đang biên dịch), bạn sẽ thấy điều này:

#line 1 "sketch_jul06b.ino"
#include "Arduino.h"
void setup ();
void loop ();
void writeHighscore(Highscore hs);
#line 1
class Highscore {
public:
  String name;
  int score;
  String toString() {
    return this->name + " - " + (String)score;
  }

  Highscore(String name, int score) {
    this->name = name;
    this->score = score;
  }
};

void setup () { }
void loop () { }

void writeHighscore(Highscore hs) 
{
// do stuff
}

Phần quan trọng là nó đặt:

void writeHighscore(Highscore hs);

trước khi lớp được khai báo.


Bạn có thể sửa lỗi bằng cách tạo nguyên mẫu hàm của riêng bạn như thế này:

void writeHighscore(Highscore hs);  // function prototype
void writeHighscore(Highscore hs) 
{
// do stuff
}

Bây giờ nó biên dịch mà không có lỗi. Nó phát hiện nguyên mẫu chức năng của riêng bạn , và do đó không tạo ra chính nó. Một vài dòng đầu tiên của tệp được tạo bây giờ là:

#line 1 "sketch_jul06b.ino"
#include "Arduino.h"
void setup ();
void loop ();
#line 1

Nguyên mẫu rắc rối đó đã biến mất.

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.