Một vài điều.
Đầu tiên, theo như tôi có thể nói NNodes
chỉ cần theo dõi kích thước. Nhưng bạn có std::vector::size()
cho điều đó. Sau đó, bạn sử dụng nó để lấy phần tử được chèn cuối cùng, nhưng bạn chỉ có thể sử dụng std::vector::back()
cho điều đó: return &N.back();
.
Ngoài ra, thông số của bạn đang được truyền theo giá trị, khi thông số này có thể được chuyển bởi tham chiếu const: const string& h
. Điều này tránh các bản sao không cần thiết, và nói chung * bạn nên chuyển mọi thứ bằng tham chiếu const thay cho giá trị bằng.
Và điều này là xấu:
node n;
N.push_back(n);
N[NNodes].setname(h);
node
có lẽ nên có một constructor mà phải mất một const string&
và đặt tên trong quá trình khởi. Bằng cách đó bạn không bao giờ có thể có một nút mà không cần một cái tên, như trong:
node n(h);
N.push_back(n);
Hoặc hơn ngắn gọn:
N.push_back(node(h));
Tốt hơn nhiều.
Thứ hai, có, vector
có thể làm mất hiệu lực con trỏ tới các phần tử; cụ thể là, bất cứ khi nào năng lực của véc-tơ cần được tăng lên. Nếu bạn có thể, reserve()
khả năng lên phía trước để tránh phân bổ lại. Trong trường hợp của bạn, bạn không thể, vì vậy bạn có thể đi hai tuyến đường khác nhau.
Tuyến đường đầu tiên là a level of indirection. Thay vì chỉ trực tiếp vào mọi thứ, hãy đưa chỉ mục của họ vào mảng. Lưu ý rằng mặc dù địa chỉ của chúng có thể thay đổi nhưng vị trí của chúng trong vector sẽ không thay đổi. Bạn sẽ có Simulator::FindNode
trả lại size_t
và trả lại N.size() - 1
. Thêm thành viên như node& GetNode(size_t index)
, chỉ cần return N[index];
(sẽ kiểm tra lỗi nếu bạn muốn). Bây giờ bất cứ khi nào bạn cần một thành viên, hãy đưa chỉ mục cho thành viên đó đến GetNode
và bạn sẽ nhận được một tham chiếu đến nút đó.
Tuyến đường khác là thay đổi vùng chứa của bạn. Bạn có thể sử dụng ví dụ deque
. Điều này không có bộ nhớ tiếp giáp, nhưng nó giống như vector
. push_back
và pop_back
vẫn là O (1) và nó vẫn có khả năng kết hợp bộ nhớ cache tốt. (Và bằng cách này, deque
nghề lưu trữ tiếp giáp cho khả năng push_front
và pop_front
trong thời gian O (1) thời gian cũng)
Điều quan trọng là deque
sẽ không con trỏ vô hiệu trong một push hoặc pop hoạt động từ một trong hai kết thúc.Nó hoạt động bằng một loại lai danh sách vectơ, nơi bạn nhận được nhiều phần lưu trữ cho các phần tử được liên kết với nhau. Thay đổi bộ nhớ cơ bản của bạn thành deque
(và không lấy hoặc đặt bất kỳ thứ gì ở giữa) và bạn có thể trỏ đến mọi thứ tốt.
Tuy nhiên, từ những gì tôi có thể cho bạn biết có một bản đồ không hiệu quả khủng khiếp. Bạn đang ánh xạ tên cho các nút. Có lẽ bạn chỉ nên sử dụng std::map
, trong đó có giao diện chính xác mà bạn đang cố gắng tạo lại. Bạn thậm chí có thể trỏ đến bất kỳ phần tử nào trong bản đồ, điều này không bao giờ làm mất hiệu lực mọi thứ.
* Nguyên tắc là, đi ngang qua const tham chiếu trừ loại là nguyên thủy (built-in như int
, double
, vv), nếu kích thước loại nhỏ hơn sizeof(void*)
, hoặc nếu bạn đang cần một bản sao của nó anyway.
Đó là, không làm điều này:
void foo(const std::string& s)
{
std::string ss(s); // make a copy, use copy
}
Nhưng làm điều này:
void foo(std::string s) // make a copy, use copy
{
}
tôi định dạng bài viết của bạn. Tôi cũng đã thay đổi mã của bạn, * xin vui lòng * đặt không gian giữa mọi thứ. Do: 'for (i = 0; i> NodeName;' thay vì 'inp_file >> NodeName;' , nó dễ đọc hơn nhiều. –
GManNickG
Tôi muốn đề nghị bạn đánh dấu câu trả lời của GMan là Được chấp nhận. Đó là cái toàn diện nhất ở đây. –
Cảm ơn tất cả mọi người đã trả lời đặc biệt là GMan và Steven Sudit, Bây giờ tôi có quá nhiều thứ để nghiên cứu và sửa đổi. – Ahmed