再会。
我需要将给定节点的所有直接子节点放入列表中。如何在 HtmlAgilityPack 中做到这一点?
示例:假设有某种结构
body
h1
p
h2
p
a
p
br
p
a
如何选择直接嵌套在正文中的所有节点?(即 a 和 br 不适合这里)
再会。
我需要将给定节点的所有直接子节点放入列表中。如何在 HtmlAgilityPack 中做到这一点?
示例:假设有某种结构
body
h1
p
h2
p
a
p
br
p
a
如何选择直接嵌套在正文中的所有节点?(即 a 和 br 不适合这里)
我需要将消息中从客户端收到的字符串附加到数据库中的现有数据中。我直接工作,使用方法:
public Order getLastOrder(int UserID)
{
Order lastOrder = null;
using (ApplicationContext db = new ApplicationContext())
{
foreach (var item in db.Orders)
{
if ((item.Customer == UserID) && (item.States == OrderStates.OnChanging))
{
lastOrder = item;
break;
}
}
}
if (lastOrder != null) return lastOrder;
else
{
throw new Exception("No avialable orders with InChanging state for user: " + UserID);
}
}
和
public void SaveOrder(Order order)
{
using (ApplicationContext db = new ApplicationContext())
{
db.Orders.Attach(order);
db.SaveChanges();
}
}
我像这样将数据添加到当前行:
_orderDataCollector = _ordersRepository.getLastOrder(message.UserId);
_orderDataCollector.Description = string.Format("{0}{1}", _orderDataCollector.Description, ("\n " + message.Text));
_ordersRepository.SaveOrder(_orderDataCollector);
问题是在向描述中添加数据时,它们没有被保存。我猜问题出在 SaveOrder(Order order);
如何解决?
我有:IDE:JB Rider 2019.3
操作系统:EndeavourOS(Arch Linux)
点网2.2
尝试运行空的 ASP.NET Core 项目时,出现错误:
Microsoft.AspNetCore.Server.Kestrel[0] Unable to start Kestrel. System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found. To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'. For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054. at Microsoft.AspNetCore.Hosting.ListenOptionsHttpsExtensions.UseHttps(ListenOptions listenOptions, Action`1 configureOptions) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func`2 createBinding) at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication`1 application, CancellationToken cancellationToken)
据我了解,dotnet 对证书发誓,因此我为 localhost 创建了一个自签名 ssl 证书,但这并没有解决问题。
如何修复此错误?
PS 关于操作系统 - 接受 ubuntu 的决定。我将尝试使它们适应我的操作系统。
PSS 在排气管中还有这条线:
Unhandled Exception: System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
在某些页面上,我需要通过单击链接来检查复选框并生成按钮单击事件:
<input type="submit" name="updatecart" id="btn_update" value="@T("Wishlist.UpdateCart")" class="button-2 update-wishlist-button" /> <!--Update Wishlist-->
脚本本身如下所示:
<script language="JavaScript">
function set_check()
{
$('#cb_remove').prop('checked', true);
}
jQuery('btn_delete').click(set_check());
let event = new Event("click");
@*$('#btn_update').dispatchEvent(event);*@<!--в @**@ заключён комментарий, т.к. работаю с Razor Pages-->
var pbUpdate;
pbUpdate = document.getElementById('btn_update');
pbUpdate.dispatchEvent("click");
</script>
最终它不起作用。Opera浏览器报错:
Uncaught TypeError: Cannot read property 'dispatchEvent' of null
at wishlist:1
如何解决?我究竟做错了什么?
如何引用一个元素以生成使用 LMB 点击它的事件?(已经在 Google 中挖了很多页面,但没有任何效果 =( )
有一些想法。你需要在 QTableView 中显示它们,以及对数据库中存在的所有视图的请求,结果是
我愿意:
{
ui->setupUi(this);
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("адрес");
db.setDatabaseName("xelfebix");
db.setUserName("xelfebix");
db.setPassword("пароль");
if(!db.open()) {
qDebug() << "Cannot open database:" << db.lastError();
}
else {
qDebug() << "Connection established";
}
QTableView view;
QSqlQueryModel model;
model.setQuery("SELECT * FROM `ТехПроцесс`;");
qDebug() << model.lastError();
view.setModel(&model);
view.show();
}
结果,整个表都是空的。我做错了什么以及如何解决?
如何正确关闭你身后的数据库连接?
void DestroyConnection()
{
QSqlDatabase::close();
}
编译器认为这段代码是错误的,并像这样发誓:
.../dialog.h:83: ошибка: call to non-static member function without an object argument
有一个应用程序范围的模式对话框,允许用户登录以进一步使用应用程序。我现在如何正确地将其包含在应用程序中?像这样尝试:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
LoginDialog * ldlg = new LoginDialog();
if(ldlg->exec() == QDialog::Accepted){
w.show();
}
return a.exec();
}
但它当然行不通。还有一个关于对话框应该返回什么的问题。据我了解,当一切正常时,您需要发送接受的信号
void LoginDialog::on_pushButton_ld_login_clicked()
{
Ops * temp = new Ops(nullptr, nullptr, ui->lineEdit_Login->text(), ui->lineEdit_Pass->text());
if(opLogin.Check(*temp)) emit accepted();
else emit rejected();
}
但话又说回来,我似乎误会了什么。如何给出正负输出呢?
表格上有2个lineEdit'a。数字键盘形式上有一堆按钮(我正在制作一个适用于触摸屏的桌面应用程序)。有必要从这个数字键盘输入数据到lineEdit有焦点的那个。
你怎么解释lineEdito'в现在焦点所在的 QPushButton 呢?
升级版:
按照@magrif 的建议,我做了以下事情:
主窗口.h
bool eventFilter(QObject *watched, QEvent *event);
QObject * m_focused;
void digiKey(QLineEdit *l);
主窗口.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
m_focused = nullptr;
/*...*/
ui->lineEdit_oPrice->installEventFilter(this);
ui->lineEdit_oAmount->installEventFilter(this);
connect(ui->pushButton_0, &QPushButton::clicked, [this]() {
if(m_focused != nullptr) {
QLineEdit* l = static_cast<QLineEdit*>(m_focused);
//do something
digiKey(l);
}
});
}
void MainWindow::digiKey(QLineEdit * l)
{
QPushButton *button = (QPushButton *)sender();
double Price;
qDebug() << "isPrice now";
Price = (l->text() + button->text()).toDouble();
l->setText(QString::number(Price));
}
最终,当点击相关按钮时,程序崩溃。
为这个字段设置了一个验证器QDoubleValidator(0, 100000, 4)
,问题是:当你在这个字段中输入一个真实的值(它表示为 1234.1234,即用逗号表示)时,这个值奇迹般地变成了零。整数被正确处理。我写了一个代理例子来证明这个异常:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QValidator>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->lineEdit->setValidator(new QDoubleValidator(0, 100000, 4));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
double _sPrice;
_sPrice = ui->label->text().toDouble();
//label располагается над LineEdit'oм
_sPrice += ui->lineEdit->text().toDouble();
ui->label->setText(QString::number(_sPrice));
}
问题 1:可能出了什么问题?怎么修?问题二:QDoubleValidator 的最高值是什么意思?据我了解,根据QValidator::Acceptable,它不会跳过[bottom, top]范围之外的值;
我正在访问 mysql 数据库:
void queryDealID()
{
QSqlQuery query;
if (!query.exec("SELECT DealID FROM st_park_bukkit ORDER BY DealID DESC LIMIT 1;"))
{
qDebug() << "Unable to execute query";
return;
}
QSqlRecord rec = query.record();
query.next();
// qDebug() << "Current DID from query " << query.value(rec.indexOf("DealID")).toString();
if(query.value(rec.indexOf("DealID")).isNull())
{
CurrentDealID = 0;
}
else
{
CurrentDealID = query.value(rec.indexOf("DealID")).toInt();
}
}
当它为空时,我的调试中会弹出以下错误:
QSqlQuery::value: not positioned on a valid record
如何解决?该代码有效,但我担心可怕的无形的事情正在发生。错误的机制是什么?
有一个类 QSqlQuery 查询的对象。查询获取某些查询的结果。如何检查 query.value 中存储的内容是否为 NULL?
有一个类(它本质上是一个结构,我会这样称呼它):
class GoodPosition
{
int GSID; //Good or Service ID
int Amount;
double Price;
int DealID; // Link to Basket ID
int NumOfCell;//number of position in current basket
/*Далее идут конструкторы и геттеры, но их я опустил, дабы не мешались*/
}
该结构位于 QVector Goods 向量中
QVector<GoodPosition> * Goods = new QVector<GoodPosition>();
我需要按索引引用向量元素和结构的字段以更改此字段。我这样做:
void CheckDublicates()// данный метод пробегает по исходному списку и уничтожает дубликатные объекты, объединяя их в один.
{
for (int i = 0; i < Goods->count(); i++)
{
for (int j = i + 1; j < Goods->count(); j++)
{
if (Goods->at(i).GSID == Goods->at(j).GSID)
{
// this->Goods->at(i).Amount = this->Goods->at(i).Amount + this->Goods->at(j).Amount;
this->Goods->at(i).Amount = addAmount(this->Goods->at(i), this->Goods->at(j));
}
}
}
}
自然,这种设计是行不通的。据我了解,这是因为 at (i) 返回一个常量,并允许我们仅使用常量方法。
问题:如何更改位于 QVector 中的结构的单元格中的数据???
这里有张桌子:
ui->tableWidget->setColumnCount(4);
for (int i = 0; i < db.gList->Goods->size(); i++)
{
ui->tableWidget->insertRow(i);
ui->tableWidget->setItem(i, 0 , new QTableWidgetItem(QString::number(i)));
ui->tableWidget->setItem(i, 1 , new QTableWidgetItem(QString::number(db.gList->Goods->at(i).GID))); //i, db.gList->Goods->at(i).gName, db.gList->Goods->at(i).gAmount, db.gList->Goods->at(i).gPrice
ui->tableWidget->setItem(i, 2 , new QTableWidgetItem(db.gList->Goods->at(i).gName));
ui->tableWidget->setItem(i, 3 , new QTableWidgetItem(QString::number(db.gList->Goods->at(i).gAmount)));
ui->tableWidget->setItem(i, 4 , new QTableWidgetItem(QString::number(db.gList->Goods->at(i).gPrice)));
}
表格中有点击表格的处理
void MainWindow::on_tableWidget_itemClicked(QTableWidgetItem *item)
{
QString strText;
int row = item->row();
for (int i = 0 ; i < ui->tableWidget->columnCount(); i++)
{
strText += ui->tableWidget->item(row, i)->text() + " ";
}
int _gsid;
int _gAmount;
double _gPrice;
_gsid = ui->tableWidget->item(row, 1)->text().toInt();
_gAmount = ui->tableWidget->item(row, 3)->text().toInt();
_gPrice = ui->tableWidget->item(row, 4)->text().toDouble();
db.bList->AddItem(_gsid, _gAmount, _gPrice);
// ui->listWidget_2->addItem(ui->tableWidget->item(row, 2)->text());
//qDebug() << strText;
}
调用时
_gPrice = ui->tableWidget->item(row, 4)->text().toDouble();
发生段错误。
我究竟做错了什么?如何解决?该过程的机制是什么?
有一些表格,点击其中的一个单元格,应该有一些动作和数据处理在一行中,但是有一个问题。当我单击时,我必须在整行中获取整个文本(假设甚至通过单元格遍历行),但我只从单元格中获取文本。
问题: 1、如何确保数据从整条线路一次传输?2.如何逐行绕过?
添加。信息:这是我第一次接触 Qt,我正在学习 Max Schlee 的教科书“Qt 5.10”。Qt 版本 - 5.11.3
Linux Mint 19.1
我使用 C++ 在 Qt Creator 中工作。尝试连接到 MySQL 我看到以下问题:
QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QMYSQL QMYSQL3 QPSQL QPSQL7
Cannot open database: QSqlError("", "Driver not loaded", "Driver not loaded")
按地址:
/home/marko/Qt/5.12.1/gcc_64/plugins/sqldrivers
以下文件:
libqsqlite.so
libqsqlite.so.debug
libqsqlmysql.so
libqsqlmysql.so.debug
libqsqlpsql.so
libqsqlpsql.so.debug
libmysqlclient 和 libssl 已经安装(在 Synaptic 中检查)
排气管
ldd ~/Qt/5.12.1/gcc_64/plugins/sqldrivers/libqsqlmysql.so
linux-vdso.so.1 (0x00007ffd29593000)
libQt5Sql.so.5 => /home/marko/Qt/5.12.1/gcc_64/plugins/sqldrivers/../../lib/libQt5Sql.so.5 (0x00007fa092088000)
libQt5Core.so.5 => /home/marko/Qt/5.12.1/gcc_64/plugins/sqldrivers/../../lib/libQt5Core.so.5 (0x00007fa0918f0000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa0916d0000)
libmysqlclient.so.18 => not found
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fa091340000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa090fa0000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa090d88000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa090990000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fa090770000)
libicui18n.so.56 => /home/marko/Qt/5.12.1/gcc_64/plugins/sqldrivers/../../lib/libicui18n.so.56 (0x00007fa0902d0000)
libicuuc.so.56 => /home/marko/Qt/5.12.1/gcc_64/plugins/sqldrivers/../../lib/libicuuc.so.56 (0x00007fa08ff18000)
libicudata.so.56 => /home/marko/Qt/5.12.1/gcc_64/plugins/sqldrivers/../../lib/libicudata.so.56 (0x00007fa08e530000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa08e328000)
libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007fa08e120000)
libglib-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007fa08de08000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa0924e8000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fa08db90000)
理论上,我应该收集 DBMS 的驱动程序源,但我不太明白具体需要做什么。在 Linux 和编程中(尚未)如何使 DBMS 驱动程序在这种情况下工作?
问题的本质是这样的——C#中有一个类,它的方法需要调试。我在 MonoDevelop 7.5 (build 1255) 中设置了一个断点。当我开始调试时,程序运行并且不会在需要的地方减慢速度。这种情况下该怎么办?
PS断点是在LeftRotate方法上调用的
操作系统:Linux Mint 18.3 64 位
IDE:MonoDevelop 7.5
using System;
namespace RBTrees
{
class MainClass
{
public enum BinSide
{
Left,
Right
}
public enum Color
{
Black,
Red
}
/// <summary>
/// Бинарное дерево поиска
/// </summary>
public class BinaryTree
{
public long? Data { get; private set; }
public BinaryTree Left { get; set; }
public BinaryTree Right { get; set; }
public BinaryTree Parent { get; set; }
public Color T_Color { get; set; }
public BinaryTree Root { get; set; } // указатель на корень дерева. Нужен для того, чтобы при поворотах не потерять корень дерева.
/// <summary>
/// Вставляет целочисленное значение в дерево
/// </summary>
/// <param name="data">Значение, которое добавится в дерево</param>
public void Insert(long data)
{
if (Data == null || Data == data)
{
Data = data;
T_Color = Color.Black;
return;
}
if (Data > data)
{
if (Left == null) Left = new BinaryTree();
Insert(data, Left, this);
/*if (this.T_Color == Color.Black) Left.T_Color = Color.Red;
if (this.T_Color == Color.Red) Left.T_Color = Color.Black;*/
}
else
{
if (Right == null) Right = new BinaryTree();
Insert(data, Right, this);
/*if (this.T_Color == Color.Black) Left.T_Color = Color.Red;
if (this.T_Color == Color.Red) Left.T_Color = Color.Black;*/
}
}
/// <summary>
/// Вставляет значение в определённый узел дерева
/// </summary>
/// <param name="data">Значение</param>
/// <param name="node">Целевой узел для вставки</param>
/// <param name="parent">Родительский узел</param>
private void Insert(long data, BinaryTree node, BinaryTree parent)
{
if (node.Data == null || node.Data == data)
{
node.Data = data;
node.Parent = parent;
if (parent.T_Color == Color.Black) node.T_Color = Color.Red;
if (parent.T_Color == Color.Red) node.T_Color = Color.Black;
return;
}
if (node.Data > data)
{
if (node.Left == null) node.Left = new BinaryTree();
Insert(data, node.Left, node);
if (parent.T_Color == Color.Black) Left.T_Color = Color.Red;
if (parent.T_Color == Color.Red) Left.T_Color = Color.Black;
}
else
{
if (node.Right == null) node.Right = new BinaryTree();
Insert(data, node.Right, node);
if (parent.T_Color == Color.Black) Right.T_Color = Color.Red;
if (parent.T_Color == Color.Red) Right.T_Color = Color.Black;
}
}
/// <summary>
/// Уставляет узел в определённый узел дерева
/// </summary>
/// <param name="data">Вставляемый узел</param>
/// <param name="node">Целевой узел</param>
/// <param name="parent">Родительский узел</param>
private void Insert(BinaryTree data, BinaryTree node, BinaryTree parent)
{
if (node.Data == null || node.Data == data.Data)
{
node.Data = data.Data;
node.Left = data.Left;
node.Right = data.Right;
node.Parent = parent;
return;
}
if (node.Data > data.Data)
{
if (node.Left == null) node.Left = new BinaryTree();
Insert(data, node.Left, node);
}
else
{
if (node.Right == null) node.Right = new BinaryTree();
Insert(data, node.Right, node);
}
}
/// <summary>
/// Определяет, в какой ветви для родительского лежит данный узел
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
private BinSide? MeForParent(BinaryTree node)
{
if (node.Parent == null) return null;
if (node.Parent.Left == node) return BinSide.Left;
if (node.Parent.Right == node) return BinSide.Right;
return null;
}
/// <summary>
/// Удаляет узел из дерева
/// </summary>
/// <param name="node">Удаляемый узел</param>
public void Remove(BinaryTree node)
{
if (node == null) return;
var me = MeForParent(node);
//Если у узла нет дочерних элементов, его можно смело удалять
if (node.Left == null && node.Right == null)
{
if (me == BinSide.Left)
{
node.Parent.Left = null;
}
else
{
node.Parent.Right = null;
}
return;
}
//Если нет левого дочернего, то правый дочерний становится на место удаляемого
if (node.Left == null)
{
if (me == BinSide.Left)
{
node.Parent.Left = node.Right;
}
else
{
node.Parent.Right = node.Right;
}
node.Right.Parent = node.Parent;
return;
}
//Если нет правого дочернего, то левый дочерний становится на место удаляемого
if (node.Right == null)
{
if (me == BinSide.Left)
{
node.Parent.Left = node.Left;
}
else
{
node.Parent.Right = node.Left;
}
node.Left.Parent = node.Parent;
return;
}
//Если присутствуют оба дочерних узла
//то правый ставим на место удаляемого
//а левый вставляем в правый
if (me == BinSide.Left)
{
node.Parent.Left = node.Right;
}
if (me == BinSide.Right)
{
node.Parent.Right = node.Right;
}
if (me == null)
{
var bufLeft = node.Left;
var bufRightLeft = node.Right.Left;
var bufRightRight = node.Right.Right;
node.Data = node.Right.Data;
node.Right = bufRightRight;
node.Left = bufRightLeft;
Insert(bufLeft, node, node);
}
else
{
node.Right.Parent = node.Parent;
Insert(node.Left, node.Right, node.Right);
}
}
/// <summary>
/// Удаляет значение из дерева
/// </summary>
/// <param name="data">Удаляемое значение</param>
public void Remove(long data)
{
var removeNode = Find(data);
if (removeNode != null)
{
Remove(removeNode);
}
}
/// <summary>
/// Ищет узел с заданным значением
/// </summary>
/// <param name="data">Значение для поиска</param>
/// <returns></returns>
public BinaryTree Find(long data)
{
if (Data == data) return this;
if (Data > data)
{
return Find(data, Left);
}
return Find(data, Right);
}
/// <summary>
/// Ищет значение в определённом узле
/// </summary>
/// <param name="data">Значение для поиска</param>
/// <param name="node">Узел для поиска</param>
/// <returns></returns>
public BinaryTree Find(long data, BinaryTree node)
{
if (node == null) return null;
if (node.Data == data) return node;
if (node.Data > data)
{
return Find(data, node.Left);
}
return Find(data, node.Right);
}
/// <summary>
/// Количество элементов в дереве
/// </summary>
/// <returns></returns>
public long CountElements()
{
return CountElements(this);
}
/// <summary>
/// Количество элементов в определённом узле
/// </summary>
/// <param name="node">Узел для подсчета</param>
/// <returns></returns>
private long CountElements(BinaryTree node)
{
long count = 1;
if (node.Right != null)
{
count += CountElements(node.Right);
}
if (node.Left != null)
{
count += CountElements(node.Left);
}
return count;
}
public void RotateLeft(BinaryTree node, BinaryTree parent)
{
BinaryTree _a = new BinaryTree();
BinaryTree _b_dLeft = new BinaryTree();
BinaryTree _b = new BinaryTree();
_b = node.Right;
_b_dLeft = node.Right.Left;
_a = node;
node = _b;
node.Left = _a;
node.Left.Right = _b_dLeft;
parent.Left = node;
}
private void RotateRight(BinaryTree node)
{
}
}
public class BinaryTreeExtensions
{
public static void Print(BinaryTree node)
{
if (node != null)
{
if (node.Parent == null)
{
Console.Write("ROOT:{0}", node.Data);
if (node.T_Color == Color.Red) Console.WriteLine(" Red");
else Console.WriteLine(" Black");
}
else
{
if (node.Parent.Left == node)
{
Console.Write("Left for {1} --> {0}", node.Data, node.Parent.Data);
if (node.T_Color == Color.Red) Console.WriteLine(" Red");
else Console.WriteLine(" Black");
}
if (node.Parent.Right == node)
{
Console.Write("Right for {1} --> {0}", node.Data, node.Parent.Data);
if (node.T_Color == Color.Red) Console.WriteLine(" Red");
else Console.WriteLine(" Black");
}
}
if (node.Left != null)
{
Print(node.Left);
}
if (node.Right != null)
{
Print(node.Right);
}
}
}
}
public static void Main(string[] args)
{
var tree = new BinaryTree();
/*tree.Insert(20);
tree.Insert(40);
tree.Insert(10);
tree.Insert(30);
tree.Insert(80);
tree.Insert(29);
tree.Insert(31);
tree.Insert(32);
tree.Insert(70);*/
tree.Insert(10);
tree.Insert(20);
tree.Insert(30);
tree.RotateLeft(tree.Right, tree);
tree.Insert(40);
tree.Insert(50);
tree.Insert(60);
tree.Insert(70);
BinaryTreeExtensions.Print(tree);
/*tree.Remove(40);
BinaryTreeExtensions.Print(tree);
tree.Remove(20);
BinaryTreeExtensions.Print(tree);*/
}
}
}
根据作业,你需要编写一个mset类来执行set类的主要功能,但是通过vector类。同时,mset 类(需要编写的类)必须是模板,而不是绑定到特定的数据类型。我声明了一个迭代器,并在构造函数中尝试将其重置为向量的开头。此行给出以下错误:
错误 3 错误 C4430:缺少类型说明符 - 预期为 int。笔记。C++ 默认不支持 int
错误 5 错误 C2146:语法错误:缺少“;” 在 id "vj" 之前
问题:可能是什么问题?
问题#2:我该如何解决这个问题?
问题#3:这个错误的机制是什么?
我不会丢掉主要代码,因为只有对默认构造函数的调用、添加元素的方法调用和打印集合的调用。
编码:
#pragma once
#include <vector>
#include <iostream>
#include <iomanip>
using namespace std;
template <typename tname>
class mset
{
public:
vector<tname> vecSet;
vector<tname>::iterator vi;
vector<tname>::iterator vj;
mset()
{
vecSet.reserve(1);
vecSet[0] = 0;
vi = vecSet.begin();
vj = vecSet.begin();
}
void Add(tname value)//добавление элемента в вектор
{
vecSet.push_back(value);
sort();
}
void Rm(int index)//уничтожение элемента
{
vi = index;
vecSet.erase(vi);
sort();
}
bool RmDb() // уничтожение дубликатов
{
sort();
for (vi = vecSet.begin(); vi != vecSet.size(); vi + 1)
{
if (vecSet[vi] == vecSet[vi + 1])
{
vecSet.erase(vi);
}
}
}
tname TakeValue(int i)//взятие значения по индексу
{
vi = vecSet.begin();
return vecSet[vi+i];
}
void sort()//сортировка
{
for (vi = vecSet.begin(); vi != vecSet.size(); vi + 1)
{
for (vj = vecSet.begin(); vj != vecSet.size() - 1; j + 1)
{
if (vecSet[vj + 1] < vecSet[vj]) swap(vecSet[vj + 1], vecSet[vj]);
}
}
}
void Print()
{
for (vi = vecSet.begin(); vi != vecSet.size(); vi+1)
{
cout << setw(1) << vecSet[vi];
}
cout << endl;
}
~mset()
{
}
private:
// vector<tname>::iterator vecIt = 0;
};
在我的程序(关于 Pavlovskaya 继承的实验室工作)中,有许多错误表明我犯了语法错误。当我开始为从 Factory.h 继承的 Triangle.h 类编写方法时,就出现了这种行为。我试图分别从 Tetragon.h 和 Rectangle.h 中删除 Triangle 和 Tetragon 类的连接 - 它没有帮助。错误显示在类标题中。如何纠正?原则上造成此类错误的原因是什么?
UPD:为了消除交叉包含,我做了一个初步的类声明,结果,在旧的错误中又增加了 147 个错误。在我描述 Triangle 中的 Move 和 PointIsIncluded 方法之前,一切正常。
我附上标题代码和错误窗口的输出:
错误 1 错误 C2061:语法错误:标识符“三角形”26 1
Error 5 error C2061: syntax error: identifier "Tetragon" 32 1 (在标题Triangle.h中第32行和第33行2次(为什么一行出现2次?)也标明了)
/*Triangle.h*/
#pragma once
#include "Factory.h"
#include <iostream>
#include "pre_tetragon.h"
using namespace std;
class Triangle: protected Factory
{
private:
const int size = 3; //размер массива
public:
float K[3]; //коэффициенты равенства уравнений
float coordx[3]; // координаты Х точек фигуры
float coordy[3]; // координаты y точек фигуры
bool IntersectLine[3]; // сколько точек находится в другой фигуре
float minx, miny, maxx, maxy; // проекции на оси
float interPointX[3]; //Х точки пересечения
/*МЕТОДЫ*/
private:
void WriteFormation()
{
cout << "formation 0" << endl;
cout << " 2 1" << endl;
}
public:
Triangle();
Triangle(float x1, float y1, float x2, float y2, float x3, float y3);
~Triangle();
void CalcBorders(); // высчитываем границы полигона
void Move(float onX, float onY);
bool IsInclude(Tetragon Tet);//ошибка тут
bool PointIsInclude(Tetragon Tet, int L);//и тут
};
/*Tetragon.h*/
#pragma once
#include "Factory.h"
#include <iostream>
#include "pre_triangle.h"
using namespace std;
class Tetragon :protected Factory
{
//ПЕРЕМЕННЫЕ
private:
const int size = 4; //размер массива
public:
float K[4]; //коэффициенты равенства уравнений
float coordx[4]; // координаты Х точек фигуры
float coordy[4]; // координаты y точек фигуры
bool IntersectLine[4];//существует ли пересечение некоторой данной линии.
float minx, miny, maxx, maxy; // Крайние точки полигона - мысы
float interPointX[4]; //Х точки пересечения
//МЕТОДЫ
public:
Tetragon(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4);
Tetragon();
~Tetragon();
void CalcBorders(); // высчитываем границы полигона
void Move(float onX, float onY);
bool IsInclude(Triangle Tri);//ошибка встречается тут
bool PointIsInclude(Triangle Tri, int L);//и тут
private:
void WriteFormation()
{
cout << "formation 0 1" << endl;
cout << " 3 2" << endl;
}
};
/*Код Factory.h*/
#pragma once
class Factory
{
protected:
float RetMaxX(float *x, int size); // Методы получения мысов фигуры
float RetMinX(float *x, int size);
float RetMaxY(float *y, int size);
float RetMinY(float *y, int size);
float CalcK(float *y, float y0, int i, int j);
float CalcPointX(float *x, float K, int i, int j);
// bool Factory::CalcEqu(float px, float *x, int i, int j, float K);
public:
Factory();
void ShowFig(float *x, float *y, int size);
void setCoordinates(float *x, float *y, int size);
void virtual WriteFormation();
~Factory();
};
/*код pre_triangle.h и pre_tetragon.h*/
#pragma once
class Triangle;
/*____________________________*/
#pragma once
class Tetragon;
/*CPP файлы*/
/*Triangle.cpp*/
#pragma once
#include "stdafx.h"
#include "Triangle.h"
#include <iostream>
#include "Tetragon.h"
using namespace std;
void Triangle::Move(float onX = 0, float onY = 0)
{
for (int i = 0; i < size; i++)
{
coordx[i] = coordx[i] + onX;
coordx[i] = coordy[i] + onY;
}
}
void Triangle::CalcBorders()
{
minx = RetMinX(coordx, 3);
miny = RetMinY(coordy, 3);
maxx = RetMaxX(coordx, 3);
maxy = RetMaxY(coordy, 3);
}
bool Triangle::PointIsInclude(Tetragon Tet, int L)
{
for (int P = 0; P < 3; P++)
IntersectLine[P] = false;
//находит коэффициент равенства уравнений
K[0] = CalcK(coordy, Tet.coordy[L], 0, 1);
K[1] = CalcK(coordy, Tet.coordy[L], 1, 2);
K[2] = CalcK(coordy, Tet.coordy[L], 2, 0);
//ищем мысы
CalcBorders();
/*Словесный алгоритм
Изначально у нас есть только У = b это у нас луч параллельный Ох и исходя из У мы должны найти Х точки пересечения.
Если он лежит в границах полигона то засчитываем пересечение, важно проверить, чтобы Х точки пересечения луча с ребром полигона был больше чем значение Х самой точки которую мы проверяем. */
if (!std::isinf(K[0]))
interPointX[0] = CalcPointX(coordx, K[0], 0, 1);
else interPointX[0] = NAN;
if (!std::isinf(K[1]))
interPointX[1] = CalcPointX(coordx, K[1], 1, 2);
else interPointX[1] = NAN;
if (!std::isinf(K[2]))
interPointX[2] = CalcPointX(coordx, K[2], 2, 0);
else interPointX[2] = NAN;
//проходим финальные условия - если точка в мысу И точки удовлетворяют уравнению - возвращаем TRUE
//здесь отображены пересечения линий. Дальше нужно подсчитать количество этих пересечений
for (int ID = 0; ID < 3; ID++)
{
if (interPointX[ID] == interPointX[ID])
{
if (interPointX[ID] > Tet.coordx[L])
{
if ((interPointX[ID] <= maxx) && (interPointX[ID] >= minx) && (Tet.coordy[L] <= maxy) && (Tet.coordy[L] >= miny))
{
IntersectLine[ID] = true;
}
}
}
}
float *mast = new float[4];
for (int i = 0; i < 3; i++)
{
mast[i] = interPointX[i];
}
mast[3] = interPointX[0];
for (int i = 0; i < 4; i++)
{
if (mast[i] == mast[i + 1])
{
IntersectLine[i] = false;
}
}
delete mast;
int Intersects = 0;
for (int ID = 0; ID < 4; ID++)
{
if (IntersectLine[ID] == true) Intersects++;
}
if (Intersects % 2 == 0)
{
return false;
}
else
{
return true;
}
}
Triangle::Triangle(float x1, float y1, float x2, float y2, float x3, float y3)
{
coordx[0] = x1;
coordx[1] = x2;
coordx[2] = x3;
coordy[0] = y1;
coordy[1] = y2;
coordy[2] = y3;
}
Triangle::Triangle()
{
WriteFormation();
for (int i = 0; i < size; i++)
{
coordx[i] = 0;
coordy[i] = 0;
}
}
Triangle::~Triangle()
{
}
/*Tetragon.cpp*/
#include "stdafx.h"
#include "Tetragon.h"
#include "Triangle.h"
/*Да гори оно уже синим пламенем*/
/*переписать isInclude
*/
Tetragon::Tetragon()
{
setCoordinates(coordx, coordy, 4);
}
void Tetragon::Move(float onX = 0, float onY = 0)
{
for (int i = 0; i < size; i++)
{
coordx[i] = coordx[i] + onX;
coordy[i] = coordy[i] + onY;
}
}
void Tetragon::CalcBorders()
{
minx = RetMinX(coordx, 4);
miny = RetMinY(coordy, 4);
maxx = RetMaxX(coordx, 4);
maxy = RetMaxY(coordy, 4);
}
/*void Tetragon::CalculateK_s(Triangle Tri)
{
K[0] = CalcK(coordy, Tri.y[0], 0, 1);
K[1] = CalcK(coordy, Tri.y[1], 1, 2);
K[2] = CalcK(coordy, Tri.y[2], 2, 3);
K[3] = CalcK(coordy, Tri.y[3], 3, 0);
}*/
bool Tetragon::PointIsInclude(Triangle Tri, int L)
{
for (int P = 0; P < 4; P++)
IntersectLine[P] = false;
//находит коэффициент равенства уравнений
K[0] = CalcK(coordy,Tri.coordy[L], 0, 1);
K[1] = CalcK(coordy, Tri.coordy[L], 1, 2);
K[2] = CalcK(coordy, Tri.coordy[L], 2, 3);
K[3] = CalcK(coordy, Tri.coordy[L], 3, 0);
//ищем мысы
CalcBorders();
/*Словесный алгоритм
Изначально у нас есть только У = b это у нас луч параллельный Ох и исходя из У мы должны найти Х точки пересечения.
Если он лежит в границах полигона то засчитываем пересечение, важно проверить, чтобы Х точки пересечения луча с ребром полигона был больше чем значение Х самой точки которую мы проверяем. */
if (!std::isinf(K[0]))
interPointX[0] = CalcPointX(coordx, K[0], 0, 1);
else interPointX[0] = NAN;
if (!std::isinf(K[1]))
interPointX[1] = CalcPointX(coordx, K[1], 1, 2);
else interPointX[1] = NAN;
if (!std::isinf(K[2]))
interPointX[2] = CalcPointX(coordx, K[2], 2, 3);
else interPointX[2] = NAN;
if (!std::isinf(K[3]))
interPointX[3] = CalcPointX(coordx, K[3], 3, 0);
else interPointX[3] = NAN;
//проходим финальные условия - если точка в мысу И точки удовлетворяют уравнению - возвращаем TRUE
//здесь отображены пересечения линий. Дальше нужно подсчитать количество этих пересечений
for (int ID = 0; ID < 4; ID++)
{
if (interPointX[ID] == interPointX[ID])
{
if (interPointX[ID] > Tri.coordx[L])
{
if ((interPointX[ID] <= maxx) && (interPointX[ID] >= minx) && (Tri.coordy[L] <= maxy) && (Tri.coordy[L] >= miny))
{
IntersectLine[ID] = true;
}
}
}
}
float *mast = new float[5];
for (int i = 0; i < 4; i++)
{
mast[i] = interPointX[i];
}
mast[4] = interPointX[0];
for (int i = 0; i < 4; i++)
{
if (mast[i] == mast[i + 1])
{
IntersectLine[i] = false;
}
}
delete mast;
int Intersects = 0;
for (int ID = 0; ID < 4; ID++)
{
if (IntersectLine[ID] == true) Intersects++;
}
if (Intersects % 2 == 0)
{
return false;
}
else
{
return true;
}
}
bool Tetragon::IsInclude(Triangle Tri)
{
bool IsInclude = false;
int Includes = 0;
for (int ID = 0; ID < 3; ID++)
{
if (PointIsInclude(Tri, ID))
{
Includes++;
}
}
if (Includes == 3) IsInclude = true;
return IsInclude;
}
Tetragon::Tetragon(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
{
coordx[0] = x1; coordy[0] = y1;
coordx[1] = x2; coordy[1] = y2;
coordx[2] = x3; coordy[2] = y3;
coordx[3] = x4; coordy[3] = y4;
}
Tetragon::~Tetragon()
{
}
/*Tetragon.cpp*/
#include "stdafx.h"
#include "Tetragon.h"
#include "Triangle.h"
Tetragon::Tetragon()
{
setCoordinates(coordx, coordy, 4);
}
void Tetragon::Move(float onX = 0, float onY = 0)
{
for (int i = 0; i < size; i++)
{
coordx[i] = coordx[i] + onX;
coordy[i] = coordy[i] + onY;
}
}
void Tetragon::CalcBorders()
{
minx = RetMinX(coordx, 4);
miny = RetMinY(coordy, 4);
maxx = RetMaxX(coordx, 4);
maxy = RetMaxY(coordy, 4);
}
/*void Tetragon::CalculateK_s(Triangle Tri)
{
K[0] = CalcK(coordy, Tri.y[0], 0, 1);
K[1] = CalcK(coordy, Tri.y[1], 1, 2);
K[2] = CalcK(coordy, Tri.y[2], 2, 3);
K[3] = CalcK(coordy, Tri.y[3], 3, 0);
}*/
bool Tetragon::PointIsInclude(Triangle Tri, int L)
{
for (int P = 0; P < 4; P++)
IntersectLine[P] = false;
//находит коэффициент равенства уравнений
K[0] = CalcK(coordy,Tri.coordy[L], 0, 1);
K[1] = CalcK(coordy, Tri.coordy[L], 1, 2);
K[2] = CalcK(coordy, Tri.coordy[L], 2, 3);
K[3] = CalcK(coordy, Tri.coordy[L], 3, 0);
//ищем мысы
CalcBorders();
/*Словесный алгоритм
Изначально у нас есть только У = b это у нас луч параллельный Ох и исходя из У мы должны найти Х точки пересечения.
Если он лежит в границах полигона то засчитываем пересечение, важно проверить, чтобы Х точки пересечения луча с ребром полигона был больше чем значение Х самой точки которую мы проверяем. */
if (!std::isinf(K[0]))
interPointX[0] = CalcPointX(coordx, K[0], 0, 1);
else interPointX[0] = NAN;
if (!std::isinf(K[1]))
interPointX[1] = CalcPointX(coordx, K[1], 1, 2);
else interPointX[1] = NAN;
if (!std::isinf(K[2]))
interPointX[2] = CalcPointX(coordx, K[2], 2, 3);
else interPointX[2] = NAN;
if (!std::isinf(K[3]))
interPointX[3] = CalcPointX(coordx, K[3], 3, 0);
else interPointX[3] = NAN;
//проходим финальные условия - если точка в мысу И точки удовлетворяют уравнению - возвращаем TRUE
//здесь отображены пересечения линий. Дальше нужно подсчитать количество этих пересечений
for (int ID = 0; ID < 4; ID++)
{
if (interPointX[ID] == interPointX[ID])
{
if (interPointX[ID] > Tri.coordx[L])
{
if ((interPointX[ID] <= maxx) && (interPointX[ID] >= minx) && (Tri.coordy[L] <= maxy) && (Tri.coordy[L] >= miny))
{
IntersectLine[ID] = true;
}
}
}
}
float *mast = new float[5];
for (int i = 0; i < 4; i++)
{
mast[i] = interPointX[i];
}
mast[4] = interPointX[0];
for (int i = 0; i < 4; i++)
{
if (mast[i] == mast[i + 1])
{
IntersectLine[i] = false;
}
}
delete mast;
int Intersects = 0;
for (int ID = 0; ID < 4; ID++)
{
if (IntersectLine[ID] == true) Intersects++;
}
if (Intersects % 2 == 0)
{
return false;
}
else
{
return true;
}
}
bool Tetragon::IsInclude(Triangle Tri)
{
bool IsInclude = false;
int Includes = 0;
for (int ID = 0; ID < 3; ID++)
{
if (PointIsInclude(Tri, ID))
{
Includes++;
}
}
if (Includes == 3) IsInclude = true;
return IsInclude;
}
Tetragon::Tetragon(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
{
coordx[0] = x1; coordy[0] = y1;
coordx[1] = x2; coordy[1] = y2;
coordx[2] = x3; coordy[2] = y3;
coordx[3] = x4; coordy[3] = y4;
}
Tetragon::~Tetragon()
{
}
/*Factory.cpp*/
#include "stdafx.h"
#include "Factory.h"
#include <iostream>
using namespace std;
void Factory::ShowFig(float *x, float *y ,int size)
{
for (int i = 0; i < size; i++)
{
cout << "x = " << x[i] << ", y = " << y[i] << ";" << endl;
}
}
void Factory::WriteFormation()
{}
void Factory::setCoordinates(float *x, float *y, int size)
{
cout << "input coordinates of points" << endl;
WriteFormation();
for (int i = 0; i < size; i++)
{
cin >> x[i] >> y[i];
}
}
float Factory::RetMaxX(float *x, int size)
{
float xMax = FLT_MIN;
for (int i = 0; i < size; i++){
if (x[i] > xMax) xMax = x[i];
}
return xMax;
}
float Factory::RetMinX(float *x, int size)
{
float xMin = FLT_MAX;
for (int i = 0; i < size; i++){
if (x[i] < xMin) xMin = x[i];
}
return xMin;
}
float Factory::RetMaxY(float *y, int size)
{
float yMax = FLT_MIN;
for (int i = 0; i < size; i++){
if (y[i] > yMax) yMax = y[i];
}
return yMax;
}
float Factory::RetMinY(float *y, int size)
{
float yMin = FLT_MAX;
for (int i = 0; i < size; i++){
if (y[i] < yMin) yMin = y[i];
}
return yMin;
}
float Factory::CalcK(float *y, float y0, int i, int j)
{
//i - первый
//j - второй
float k = 0;
k = (y0 - y[i]) / (y[j] - y[i]);
return k;
}
float Factory::CalcPointX(float *x, float K, int i, int j)
{
float x0 = 0;
x0 = K * (x[j] - x[i]) + x[i];//X[j] - x2, x[i] - x1, x0 - искомый х
return x0;
}
/*bool Factory::CalcEqu(float px, float *x, int i, int j, float K)
{
if ((px - x[i]) / (x[j] - x[i]) == K)
return true;
}*/
Factory::Factory()
{
}
Factory::~Factory()
{
}
问题如下。我需要在 TakeElement 方法中使用 m 来获取存储在动态结构中的数字。它是数字本身,而不是它的链接。我怎样才能做到这一点?

#pragma once
#include "vset.h"
#include <iostream>
#include <set>
using namespace std;
/*
Собирать множества можно по такому принципу
В случае сложения
Собираем в третье множество сначала первую цепочку, а затем вторую. Далее уничтожаем дубликаты, а затем обновляем индентификаторы.
В случае логическиго И мы
Сравниваем элементы и их IDы. Если они равны, то записываем их в третью цепочку.
В случае разности множеств мы Складываем две цепочки в которых делаем очищение от дубликатов. Затем в Третьей цепочки спускаемся вниз.
Во время спуска будет происходить т.н. перебор по счётчику(Да Долго). То бишь мы берём первый элемент и сравниваем с остальными. Если попались дубликаты, то мы их удаляем.
Затем уничтожаем первый элемент. Обновляем Индентификаторы. Идём сначала и так до тех пор пока не дойдём до конца множества. Флаг конца множества - указатель на следующий элемент равный NULL
*/
vset::SingleList * vset::MakeFirst(int d)
{
SingleList *cRec = new SingleList;
cRec->Data = d; cRec->Id = 0; cRec->next = 0; cRec->prev = 0;
return cRec;
}
void vset::AddElement(vset::SingleList **last, int d)
{
vset::SingleList *cRec = new SingleList;
cRec->Data = d; cRec->next = 0; cRec->prev = *last;
(*last)->next = cRec;
*last = cRec;
RefreshIds(vset::ihead);
}
vset::SingleList * vset::Search(SingleList * const pbeg, int d)
{
SingleList *cRec = pbeg;
while (cRec)
{
if (cRec->Data == d)break;
cRec = cRec->next;
}
return cRec;
}
vset::SingleList * vset::SearchId(SingleList * const pbeg, int id)
{
SingleList *cRec = pbeg;
while (cRec)
{
if (cRec->Id == id)break;
cRec = cRec->next;
}
return cRec;
}
int vset::TakeElement(vset::SingleList *Rec)
{
int m = 0;
m = Rec->Data;
return m;
}
bool vset::Remove(vset::SingleList **head, vset::SingleList **last, int key)//его нужно перегрузить
{
if (SingleList *pkey = Search(*head, key))
{
if (pkey == *head)
{
*head = (*head)->next;
(*head)->prev = 0;
}
else if (pkey == *last)
{
*last = (*last)->prev;
(*last)->next = 0;
}
else {
(pkey->prev)->next = pkey->next;
(pkey->next)->prev = pkey->prev;
}
delete pkey;
return true;
}
return false;
}
bool vset::RemoveId(vset::SingleList **head, vset::SingleList **last, int id)//его нужно перегрузить
{
if (SingleList *pkey = SearchId(*head, id))
{
if (pkey == *head)
{
*head = (*head)->next;
(*head)->prev = 0;
}
else if (pkey == *last)
{
*last = (*last)->prev;
(*last)->next = 0;
}
else {
(pkey->prev)->next = pkey->next;
(pkey->next)->prev = pkey->prev;
}
delete pkey;
return true;
}
return false;
}
void vset::PrintList(vset::SingleList * const head)
{
vset::SingleList *cRec = head;
while (cRec)
{
cout << cRec->Data <<" ";
cRec = cRec->next;
}
}
void vset::DestroyDublicats(vset::SingleList * const head)
{
/*
Берём первый элемент множества и сравниваем с последующими. Найденные дубликаты уничтожаем. Обновляем IDы
*/
vset::SingleList *cRec = head;//cRec - указатель на захваченный элемент множества который мы будем сравнивать с вторым указателем. Сокращение от Current Record
vset::SingleList *tRec = head;//tRec - указатель на сравниваемый элемент множества с которым мы будем сравнивать первый указатель. Сокращение от Temporary Record
while (cRec)
{
while (tRec)
{
if (tRec->next != NULL)
tRec = tRec->next;
else break;
if ((cRec->Data == tRec->Data) && (cRec->Id != tRec->Id))
{
int tId = tRec->Id;
vset::RemoveId(&ihead, &ilast, tId);
break;
}
}
tRec = head;
if (cRec->next != NULL)
cRec = cRec->next;
else break;
}
RefreshIds(ihead);
}
vset vset::Combine(vset::SingleList * const head, class vset &sSet)
{
this->cRec1 = head;
this->cRec2 = sSet.ihead;
vset nSet(cRec1->Data);
cRec1->next;
int num = 0;
num = TakeElement(cRec1);
while (cRec1)
{
nSet.AddElement(num);
}
}
void vset::PrintIds(vset::SingleList * const head)
{
vset::SingleList *cRec = head;
while (cRec)
{
cout << cRec->Id << " ";
cRec = cRec->next;
}
}
void vset::RefreshIds(vset::SingleList * const head)
{
int Id = 0;
vset::SingleList *cRec = head;
while (cRec)
{
cRec->Id = Id;
Id++;
cRec = cRec->next;
}
}
vset::vset()
{
SingleList *ihead = MakeFirst(0);
SingleList *ilast = ihead;
}
vset::vset(int d)
{
ihead = MakeFirst(d);
ilast = ihead;
}
vset::~vset()
{
}
问题如下:我在类中使用列表(禁止使用 STL)我至少编写了方法。此外,当我在 main 中描述实例并尝试调用 addElement 方法时,会发生内存访问错误。怎样成为?为什么会这样?
Main.cpp 列表
#include "stdafx.h"
#include "vset.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
vset a;
a.AddElement(&a.ilast, 5);
// a.AddElement(&a.last, 7);
a.PrintList(a.ihead);
return 0;
}
列出vset.cpp类的实现
#pragma once
#include "vset.h"
#include <iostream>
using namespace std;
vset::SingleList * vset::makeFirst(int d)
{
SingleList *cRec = new SingleList;
cRec->Data = d; cRec->next = 0; cRec->prev = 0;
return cRec;
}
void vset::AddElement(vset::SingleList **last, int d)
{
vset::SingleList *cRec = new SingleList;
cRec->Data = d; cRec->next = 0; cRec->prev = *last;
(*last)->next = cRec;
*last = cRec;
}
vset::SingleList * vset::search(SingleList * const pbeg, int d)
{
SingleList *cRec = pbeg;
while (cRec)
{
if (cRec->Data == d)break;
cRec = cRec->next;
}
return cRec;
}
bool vset::remove(vset::SingleList **head, vset::SingleList **last, int key)
{
if (SingleList *pkey = search(*head, key))
{
if (pkey == *head)
{
*head = (*head)->next;
(*head)->prev = 0;
}
else if (pkey == *last)
{
*last = (*last)->prev;
(*last)->next = 0;
}
else {
(pkey->prev)->next = pkey->next;
(pkey->next)->prev = pkey->prev;
}
delete pkey;
return true;
}
return false;
}
vset::SingleList * vset::insert(vset::SingleList * const head, vset::SingleList **last, int key, int d)
{
if (SingleList *pkey = search(head, key))
{
SingleList *cRec = new SingleList;
cRec->Data = d; cRec->next = pkey->next;
cRec->prev = pkey; pkey->next = cRec;
if (pkey != *last) (cRec->next)->prev = cRec;
else *last = cRec;
return cRec;
}
return 0;
}
void vset::PrintList(vset::SingleList * const head)
{
SingleList *cRec = head;
while (cRec)
{
cout << cRec->Data << " ";
cRec = cRec->next;
}
}
void getData()
{
}
vset::vset()
{
SingleList *ihead = makeFirst(0);
SingleList *ilast = ihead;
// getLast(&last);
}
vset::vset(int d)
{
SingleList *ihead = makeFirst(d);
SingleList *ilast = ihead;
}
/*vset::SingleList getLast(vset::SingleList **last)
{
static vset::SingleList **olast;
if (!last) olast = last;
return **olast;
}*/
vset::~vset()
{
}
vset.h 接口
#pragma once
class vset
{
public:
struct SingleList
{
int Data;
SingleList *next;
SingleList *prev;
};
SingleList *ihead;
SingleList *ilast;
public:
vset();
vset::vset(int d);
~vset();
SingleList * makeFirst(int d);
void AddElement(SingleList **last, int d);
SingleList * search(SingleList * const pbeg, int d);
bool remove(SingleList **head, SingleList **last, int key);
SingleList * insert(SingleList * const head, SingleList **last, int key, int d);
void PrintList(SingleList * const head);
void getData();
vset::SingleList getLast(vset::SingleList);
};