cuốn sách gpt4 ai đã làm

Thiết kế một hệ thống thư mục/tập tin?

In lại Tác giả: Taklimakan Thời gian cập nhật: 2023-11-03 00:20:43 26 4
mua khóa gpt4 Nike

Tôi đang cố gắng tạo một hệ thống thư mục/tệp tương tự như hệ thống được sử dụng trong hầu hết các hệ điều hành.
Về cơ bản, tôi đã xác định được ba lớp nên được sử dụng. Tài liệu,Thư mụcvà một lớp cơ sở công cộng. Vì mục đích sáng tạo, chúng tôi gọi nó làChung.
Tôi nghĩ ba tựa game này sẽ trông như thế này:

bình thường

lớp chung {
string m_name; // tất cả file và thư mục đều có tên
Thư mục* m_parent; // tất cả các tập tin và thư mục đều có thể có cha

public:
virtual void open() = 0; // được thực thi khi người dùng mở thư mục hoặc tập tin
virtual void draw() const; // tất cả các tập tin và thư mục có thể được in
virtual void setParent(Thư mục* cha mẹ);
Thư mục ảo* getParent() const;
};

thư mục.h
thư mục lớp : public Common {
vector m_children; // thư mục có thể chứa các tập tin và thư mục khác
// trong khi các tập tin không thể

public:
virtual void open(); // thư mục mở ra; về cơ bản hiển thị nội dung
virtual void draw() const; // thư mục vẽ khác
};

tài liệu
Tệp lớp : public Common {
// không hẳn là "file", chúng chỉ gọi một hàm khi mở
funcptr m_openAction;

public:
virtual void open(); // gọi m_openAction() khi được mở
};

Như bạn có thể thấy vấn đề xảy ra với lớp cơ sở của tôi Chungcó thể biết các lớp con của nó Thư mục, đây là hành vi xấu và không nên làm (ít nhất là theo giáo viên của tôi).
Điều này ngăn cản tôi mã hóa hệ thống theo kế hoạch.

Một hệ thống như vậy nên được thiết kế như thế nào?

câu trả lời hay nhất

Thiết kế hiện tại của bạn không yêu cầuChungđể "biết các lớp con của nó"Thư mục”。
nó chỉ yêu cầuChung tiêu đề để khai báo sự tồn tại của một lớp như vậy
作为Thư mục:

thư mục lớp; // Chuyển tiếp khai báo

lớp chung {
string m_name; // tất cả file và thư mục đều có tên
Thư mục* m_parent; // tất cả các tập tin và thư mục đều có thể có cha

public:
virtual ~Common(); // Đừng quên hàm hủy ảo!
virtual void open() = 0; // được thực thi khi người dùng mở thư mục hoặc tập tin
virtual void draw() const; // tất cả các tập tin và thư mục có thể được in
virtual void setParent(Thư mục* cha mẹ);
Thư mục ảo* getParent() const;
};

Không có chu kỳ phụ thuộc ở đây.

Nếu vì lý do học thuật nào đó mà bạn phải có hoặc thậm chí không có
Đề cập đến bất kỳ lớp con nào, bạn có thể tạo một lớp cơ sở đa hình như thế này:
nút lớp {
string m_name; // tất cả file và thư mục đều có tên
Node* m_parent; // tất cả các file và thư mục đều có thể có cha

public:
virtual ~Node(); // Đừng quên hàm hủy ảo!
virtual void open() = 0; // được thực thi khi người dùng mở thư mục hoặc tập tin
virtual void draw() const; // tất cả các tập tin và thư mục có thể được in
virtual void setParent(Node* parent);
Nút ảo* getParent() const;
};

Với thiết kế này, setParent(Nút* cha)phương pháp sẽ có
Bao gồm kiểm tra thời gian chạy để đảm bảo Nút*tham số cha mẹ实际上是一个 Thư mục*,例如
Thư mục *pf = Dynamic_cast(cha mẹ);

Trong trường hợp này, nó cũng yêu cầu kiểu trả về không null, qua đó
Cho biết sự thành công hay thất bại. Nó quanh co thay vì chỉ làm lớpThư mụctuyên bố.

Tiếp tụcđể giải quyết câu hỏi tiếp theo của OP.

Bên trong Common's setParent() Tôi phải gọi tới m_children; điều này dẫn đến lỗi. Ngay cả khi tôi đưa folder.h vào common.cpp, tôi không thể truy cập các thành viên riêng của thư mục.



Câu trả lời trước của tôi chỉ giới hạn ở việc hiển thị cho bạn điều gì "ngăn cản bạn mã hóa hệ thống như bạn dự định"
Thực ra là không.

Vấn đề bạn đang gặp phải hiện nay là một số thư mục fĐặt làm thư mục mẹ của một số thư mục
nút nKhông phải là một hoạt động độc lập trên nút (tệp hoặc thư mục). fchỉ có thể
nếu như nTrở thành một trong số họ đồng thời có nghĩa là trở thành một cách hiệu quả ncha mẹ của fcủa trẻ em. Vì thế ở n.setParent(cha mẹ), được thực hiện cùng lúc với việc cài đặt
bạn muốn n.mParent == cha mẹ添加到 ncủa cha mẹ->m_con cái;
Nhưng nút m_conKhông thể truy cập n.

Câu hỏi này mang ý nghĩa nặng nề cho thiết kế của bạn. Nếu bạn đặt cha mẹ và thêm con
phải luôn xảy ra cùng nhau thì chúng thực sự là cùng một thao tác -set-parent-add-child
-Chỉ có phương thức gọi là khác nhau: nó được gọi từ cha mẹ hay con. nếu có Chungcung cấp setParent(Thư mục *)lý do thì cũng tốt như nhau Thư mụccung cấp addChild(Chung *)lý do, và tất cả họ đều phải làm điều tương tự.

Liệu điều này có cho thấy static void Common::link(Thư mục * cha, Chung * con)Liệu chúng có thể được thay thế công khai tốt hơn không? Có thể vậy; nhưng bạn bắt đầu Common::setParent(Thư mục *),
Điều này là hợp lý; do đó hãy so sánh nó với Thư mục::addChild(Chung *)Sự kết hợp cũng hợp lý,
Sau đó chúng ta có thể khiến họ làm điều tương tự bằng cách gọi điện cho nhau.

Sau đó, chúng ta cũng cần xét rằng do pCommon->setParent(pFolder)Đúng
Tương đương với pFolder->addChild(pCommon), bạn cũng cần
Xóa một nút khỏi nút cha của nó vì trước đó bạn có thể thêm một cách hiệu quả;
Một nút mà cha mẹ của nó phải được loại bỏ khỏi nút cha hiện có của nó, nếu có. Và
Hoạt động này có thể mang lại lợi ích cho mã máy khách; Thư mục::removeChild(Chung *)Điều đó cũng đúng Thư mụcgiao diện.
Thư mục::addChild(Chung * pnode)Thư mục::removeChild(Common * pnode)Đúng
Bạn thiếu quản lý thành viên riêng tư Thư mục::m_childrengiao diện.

Tiếp theo, hãy xem xét rằng mỗi phương pháp phải
Chắc chắn nútLiệu nó có thực sự là con của thư mục này hay không: không được thêm vào
Thư mục con vào một thư mục đã là thư mục con và bạn không thể xóa thư mục con không phải là thư mục con.
因此 Thư mục::find(Chung * pnode)Nó cũng sẽ hữu ích - ít nhất là cho việc thực hiện
(riêng tư), có thể là mã máy khách (công khai): bạn quyết định.

Sau đó, hãy xem xét Thư mục::find(Chung * pnode)Yêu cầu
Một cách khác: bool Common::operator==(Const chung & khác). Hãy nói theo cách này
Các nút bằng nhau nếu chúng có cùng tên.
Chung::clearParent()Tôi cũng nghĩ đến điều đó nhưng tôi đã gạt nó sang một bên.

Những ý tưởng này là đủ cho các yêu cầu thực hiện sau đây, cụ thể là
Chưa đầy đủ, chưa tối ưu và không thực tế nhưng minh họa cách nối các điểm mà chúng ta có
Vừa quyết định vượt qua rào cản truy cập thành viên
vẫn đang chặn bạn, điều này không thực tế vì nó bỏ qua
Vấn đề chung với quyền sở hữu giả định của các đối tượng động
bằng phương pháp của nó Thư mục*Chung*Các thông số đã được giải quyết.
Bạn có thể tự mình xử lý (và bạn có thể muốn điều tra)
std::shared_ptr
std::unique_ptr,mặc dù
Đây là nhiều hơn nữa
Ngoài các cơ sở vật chất tiên tiến bạn nên sử dụng trong dự án này).

chung.h
#ifndef COMMON_H
#defineCOMMON_H

#include

#include

Thư mục lớp;

lớp chung {
std::string m_name;
Thư mục* m_parent;

public:
rõ ràng Common(std::string const & name)
: m_name(name),m_parent(nullptr){}
ảo ~Common(){};
virtual void open() { /*Sao cũng được*/}
virtual void draw() const {/*Sao cũng được*/}
Thư mục ảo* getParent() const { return m_parent };
virtual void setParent(Thư mục* cha mẹ);
toán tử bool==(Const chung & khác) const {
trả lại m_name == other.m_name;
}
toán tử bool!=(Const chung & khác) const {
return !(*this == other);
}
#if 1 //Kiểm tra
std::string const & name() const {
trả lại m_name;
}
std::string parent() const;

danh sách trống ảo() const {
std::cout << name() << " (trong " << parent() << ')' << std::endl ;
}
#endif
};

#endif // EOF

thư mục.h
#ifndef FOLDER_H
#xác định FOLDER_H

#include "common.h"
#include

thư mục lớp : public Common {
std::vector m_children;

std::vector::iterator find(Common const * child) {
auto i = m_children.begin();
for ( ;i != m_children.end() && **i != *child; ++i) {}
trả lại tôi;
}

public:
Thư mục rõ ràng(std::string const & name)
: Chung(tên){}
virtual void open(){/*Sao cũng được*/}
virtual void draw() const {/*Sao cũng được*/}
void addChild(Common * child) {
auto par = child->getParent();
if (par && par != this) {
par->removeChild(con);
}
if (find(child) == m_children.end()) {
m_children.push_back(con);
m_children.back()->setParent(this);
}
}
void RemoveChild(Const chung * con) {
tự động ở đâu = tìm (con);
if (where != m_children.end()) {
m_children.erase(ở đâu);
}
}
#if 1 //Kiểm tra
danh sách trống() const {
std::cout << name() << " {" << std::endl;
for (Const chung * con : m_children) {
con->danh sách();
}
std::cout << '}' << std::endl;
}
#endif
};

#endif //EOF

tập tin.h
#ifndef FILE_H
#defineFILE_H

#include "common.h"

Tệp lớp : public Common {
// Bất cứ điều gì
public:
Tệp rõ ràng(std::string const & name)
: Chung(tên){}
virtual void open(){/*Sao cũng được*/};

};

#endif // EOF

chung.cpp
#include "common.h"
#include "thư mục.h"

void Common::setParent(Folder* parent) {
auto par = getParent();
if (par && par != parent) {
par->removeChild(this);
}
m_parent = cha mẹ;
m_parent->addChild(cái này);
}

#if 1 //Kiểm tra
std::string Common::parent() const {
trả về m_parent ? m_parent->name() : "";
}
#endif

Một chương trình thử nghiệm:
#include "common.h"
#include "thư mục.h"
#include "file.h"

int main()
{
Thư mục *fo0 = Thư mục mới("folder0");
Tệp * fi0 = Tệp mới("file0");
Tệp * fi1 = Tệp mới("file1");
fo0->addChild(fi0);
fi1->setParent(fo0);
fo0->addChild(fi0); // Nhân đôi
fi1->setParent(fo0); // Trùng lặp
// Hiện tại có 2 file trong thư mục fo0
fo0->list();
Thư mục *fo1 = Thư mục mới("folder1");
fo1->addChild(fi1);
fi0->setParent(fo1);
fo1->addChild(fi1); // Nhân đôi
fi0->setParent(fo1); // Trùng lặp
// Hiện tại có 0 file trong thư mục fo0
// Hiện tại có 2 file trong thư mục fo1
fo0->list();
fo1->danh sách();
xóa fo0;
xóa fo1;
xóa fi0;
xóa fi1;
return 0;
}

Giới thiệu về c++ - Thiết kế hệ thống thư mục/file? , chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/17013321/

26 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress