学习托管C ++泛型[关闭](Learning managed C++ generics [closed])

编程入门 行业动态 更新时间:2024-10-19 08:51:55
学习托管C ++泛型[关闭](Learning managed C++ generics [closed])

我在学校的托管C ++中创建了一个小型BST项目。 工作得很好,但现在我想弄清楚如何使用泛型(第一个项目使用int)来做同样的项目。 对于我的生活,我无法看到我从根本上搞砸了什么。 希望方向。

GenericNodeClass.h:

/* GenericNodeClass.h. Created by Ed Thompson for IS375, C++ Intermediate, City University of Seattle. GenericNodeClass.h provides for members for creation of a generic binary tree */ #pragma once #include "stdafx.h" #include <iostream> #include <deque> #include <climits> using namespace std; using namespace System; using namespace System::Collections; using namespace System::Collections::Generic; generic <typename T> where T : IComparable<T>, IEquatable<T> ref class Node { public: T data; T parent; Node<T> ^ left; Node<T> ^ right; // Constructor that takes one parameter: // a T, representing the value of a new node Node(T n) { data = n; } };

BinarySearchTreeClass.h

#include "stdafx.h" #include <iostream> #include <deque> #include <climits> #include "GenericNodeClass.h" using namespace std; using namespace System; using namespace System::Collections; using namespace System::Collections::Generic; generic <typename T> where T : IComparable<T> , IEquatable<T> ref class BinarySearchTreeClass { public: Node<T>^ rootNode; T _p; // constructors // default BinarySearchTreeClass(){} BinarySearchTreeClass(T t) { // create a new Node in the Binary Search Tree rootNode = gcnew Node<T> (t); } // method to return a node if it exists in the tree // takes two parameters: an instance of the Node class, and a // value representing the value of the node to be looked up Node<T> ^ lookUp(Node<T> ^node, T key) { if(node == nullptr) return node; if(node->data == key) return node; else { if (node->data->CompareTo(key) < 0) return lookUp(node->right, key); else return lookUp(node->left, key); } } // method to create new node. Method takes two parameters: // a parameter of the value for the node data, and a value // for the node's parent. Node<T> ^newNode(T key, T parent) { Node<T> ^node = gcnew Node<T>(key); node->data = key; node->left = nullptr; node->right = nullptr; node->parent = parent; return node; } // insertNode method inserts a new node into an existing // Binary Search Tree. This method takes two parameters: // an instance of Node<T> (node), and a value of T, // representing the value of the node being inserted Node<T> ^insertNode(Node<T> ^node, T input) { Node<T> ^returnNode; if (node != nullptr) _p = node->data; // if the node is non-existant, create a new node // with the value of the parameter 'input' and the // value of the new node's parent (_p). if (node == nullptr) { // pass class variable _p to set value // of the new node's parent value. returnNode = newNode(input, _p); return returnNode; } // if the input parameter value is less than // or equal to the node value, insert node using // the left hand node leaf of the current node // as starting point if (input->CompareTo(node->data) < 0) { // set variable p to value of node->data value (this // will be the parent of the new node) _p = node->data; node->left = insertNode(node->left, input); } // if the input parameter value is greater than // the node value, insert node using the right hand // node leaf of the current node as starting point else { _p = node->data; node->right = insertNode(node->right, input); } return node; } // method to find the left most node in a Binary Search Tree // takes an instance of Node<T> as parameter Node<T> ^leftMost(Node<T> ^node) { if (node == nullptr) return nullptr; while (node->left != nullptr) node = leftMost(node->left); return node; } // method of return the right most node in a Binary Search Tree // takes an instance of Node<T> as parameter Node<T> ^rightMost(Node<T> ^node) { if (node == nullptr) return nullptr; while (node->right != nullptr) node = rightMost(node->right); return node; } // method to return the size of a Binary Tree // takes an instance of Node<T> as parameter int treeSize(Node<T> ^node) { if(node == nullptr || node->left == nullptr && node->right == nullptr) return 0; else return treeSize(node->left) + 1 + treeSize(node->right); } // method that prints to console the value of each node from lowest to highest // takes an instance of Node<T> as parameter void printTreeInOrder(Node<T> ^node) { if (node != nullptr) { printTreeInOrder(node->left); Console::WriteLine(node->data); printTreeInOrder(node->right); } } // method that prints to console a graphic representation of a binary tree // takes an instance of Node<T> as parameter void printGraphicRepresentation(Node<T> ^node) { // the width of the tree is the max height /2 (?) // need to know how wide the tree is // At treeWidth / 2, print node // on new line, at nodePosition - 1, if node has a left, print a "/" // on same line, at nodePosition + 1, if node has a right, print a "\" } // method that prints to console all members of a given node // takes an instance of Node<T> as parameter void printNodeMembers(Node<T> ^node) { Console::WriteLine("Members of Node " + node->data + " include: "); if (node->parent != nullptr) Console::WriteLine("Parent: " + node->parent); else Console::WriteLine("This node has no parent."); if (node->left != nullptr) Console::WriteLine("Left-member: " + node->left->data); else Console::WriteLine("This node has no left-member."); if (node->right != nullptr) Console::WriteLine("Right-Member: " + node->right->data); else Console::WriteLine("This node has no right-member."); } };

TestClass.cpp

#include "stdafx.h" #include "GenericNodeClass.h" #include "BinarySearchTreeClass.h" #include <iostream> using namespace std; using namespace System; using namespace System::IO; using namespace System::Collections::Generic; int main () { BinarySearchTreeClass<int>^ BTree = gcnew BinarySearchTreeClass<int>(); // instantiate new Node instance with starter value Node<int> ^rootNode = gcnew Node<int>(5); // insert additional nodes BTree->insertNode(rootNode, 3); BTree->insertNode(rootNode, 7); BTree->insertNode(rootNode, 4); BTree->insertNode(rootNode, 6); BTree->insertNode(rootNode, 2); BTree->insertNode(rootNode, 9); BTree->insertNode(rootNode, 1); BTree->insertNode(rootNode, 8); BTree->insertNode(rootNode, 0); BTree->insertNode(rootNode, 10); BTree->insertNode(rootNode, 12); BTree->insertNode(rootNode, 11); Console::WriteLine("The value of the left-most node in this tree is: " + BTree->leftMost(rootNode)->data); Console::WriteLine("The value of the right-most node in this tree is: " + BTree->rightMost(rootNode)->data); Console::WriteLine("The size of this Binary Search Tree is: " + BTree->treeSize(rootNode)); Console::WriteLine("Printing Binary Search Tree in order: "); BTree->printTreeInOrder(rootNode); // TO EXAMINE THE PROPERTIES OF A GIVEN NODE, CHANGE THE SECOND PARAMETER OF // THE lookUp METHOD IN THE FOLLOWING LINE OF CODE TO THE NODE DESIRED TO BE EXAMINED BTree->printNodeMembers(BTree->lookUp(rootNode, 7)); Console::WriteLine(); return 0; }

I created a small BST project in managed C++ for school. Worked well, but now I'm trying to figure out how to do the same project using generics (first project used int). For the life of me I cannot see what I'm fundamentally screwing up. Hoping for direction.

GenericNodeClass.h:

/* GenericNodeClass.h. Created by Ed Thompson for IS375, C++ Intermediate, City University of Seattle. GenericNodeClass.h provides for members for creation of a generic binary tree */ #pragma once #include "stdafx.h" #include <iostream> #include <deque> #include <climits> using namespace std; using namespace System; using namespace System::Collections; using namespace System::Collections::Generic; generic <typename T> where T : IComparable<T>, IEquatable<T> ref class Node { public: T data; T parent; Node<T> ^ left; Node<T> ^ right; // Constructor that takes one parameter: // a T, representing the value of a new node Node(T n) { data = n; } };

BinarySearchTreeClass.h

#include "stdafx.h" #include <iostream> #include <deque> #include <climits> #include "GenericNodeClass.h" using namespace std; using namespace System; using namespace System::Collections; using namespace System::Collections::Generic; generic <typename T> where T : IComparable<T> , IEquatable<T> ref class BinarySearchTreeClass { public: Node<T>^ rootNode; T _p; // constructors // default BinarySearchTreeClass(){} BinarySearchTreeClass(T t) { // create a new Node in the Binary Search Tree rootNode = gcnew Node<T> (t); } // method to return a node if it exists in the tree // takes two parameters: an instance of the Node class, and a // value representing the value of the node to be looked up Node<T> ^ lookUp(Node<T> ^node, T key) { if(node == nullptr) return node; if(node->data == key) return node; else { if (node->data->CompareTo(key) < 0) return lookUp(node->right, key); else return lookUp(node->left, key); } } // method to create new node. Method takes two parameters: // a parameter of the value for the node data, and a value // for the node's parent. Node<T> ^newNode(T key, T parent) { Node<T> ^node = gcnew Node<T>(key); node->data = key; node->left = nullptr; node->right = nullptr; node->parent = parent; return node; } // insertNode method inserts a new node into an existing // Binary Search Tree. This method takes two parameters: // an instance of Node<T> (node), and a value of T, // representing the value of the node being inserted Node<T> ^insertNode(Node<T> ^node, T input) { Node<T> ^returnNode; if (node != nullptr) _p = node->data; // if the node is non-existant, create a new node // with the value of the parameter 'input' and the // value of the new node's parent (_p). if (node == nullptr) { // pass class variable _p to set value // of the new node's parent value. returnNode = newNode(input, _p); return returnNode; } // if the input parameter value is less than // or equal to the node value, insert node using // the left hand node leaf of the current node // as starting point if (input->CompareTo(node->data) < 0) { // set variable p to value of node->data value (this // will be the parent of the new node) _p = node->data; node->left = insertNode(node->left, input); } // if the input parameter value is greater than // the node value, insert node using the right hand // node leaf of the current node as starting point else { _p = node->data; node->right = insertNode(node->right, input); } return node; } // method to find the left most node in a Binary Search Tree // takes an instance of Node<T> as parameter Node<T> ^leftMost(Node<T> ^node) { if (node == nullptr) return nullptr; while (node->left != nullptr) node = leftMost(node->left); return node; } // method of return the right most node in a Binary Search Tree // takes an instance of Node<T> as parameter Node<T> ^rightMost(Node<T> ^node) { if (node == nullptr) return nullptr; while (node->right != nullptr) node = rightMost(node->right); return node; } // method to return the size of a Binary Tree // takes an instance of Node<T> as parameter int treeSize(Node<T> ^node) { if(node == nullptr || node->left == nullptr && node->right == nullptr) return 0; else return treeSize(node->left) + 1 + treeSize(node->right); } // method that prints to console the value of each node from lowest to highest // takes an instance of Node<T> as parameter void printTreeInOrder(Node<T> ^node) { if (node != nullptr) { printTreeInOrder(node->left); Console::WriteLine(node->data); printTreeInOrder(node->right); } } // method that prints to console a graphic representation of a binary tree // takes an instance of Node<T> as parameter void printGraphicRepresentation(Node<T> ^node) { // the width of the tree is the max height /2 (?) // need to know how wide the tree is // At treeWidth / 2, print node // on new line, at nodePosition - 1, if node has a left, print a "/" // on same line, at nodePosition + 1, if node has a right, print a "\" } // method that prints to console all members of a given node // takes an instance of Node<T> as parameter void printNodeMembers(Node<T> ^node) { Console::WriteLine("Members of Node " + node->data + " include: "); if (node->parent != nullptr) Console::WriteLine("Parent: " + node->parent); else Console::WriteLine("This node has no parent."); if (node->left != nullptr) Console::WriteLine("Left-member: " + node->left->data); else Console::WriteLine("This node has no left-member."); if (node->right != nullptr) Console::WriteLine("Right-Member: " + node->right->data); else Console::WriteLine("This node has no right-member."); } };

TestClass.cpp

#include "stdafx.h" #include "GenericNodeClass.h" #include "BinarySearchTreeClass.h" #include <iostream> using namespace std; using namespace System; using namespace System::IO; using namespace System::Collections::Generic; int main () { BinarySearchTreeClass<int>^ BTree = gcnew BinarySearchTreeClass<int>(); // instantiate new Node instance with starter value Node<int> ^rootNode = gcnew Node<int>(5); // insert additional nodes BTree->insertNode(rootNode, 3); BTree->insertNode(rootNode, 7); BTree->insertNode(rootNode, 4); BTree->insertNode(rootNode, 6); BTree->insertNode(rootNode, 2); BTree->insertNode(rootNode, 9); BTree->insertNode(rootNode, 1); BTree->insertNode(rootNode, 8); BTree->insertNode(rootNode, 0); BTree->insertNode(rootNode, 10); BTree->insertNode(rootNode, 12); BTree->insertNode(rootNode, 11); Console::WriteLine("The value of the left-most node in this tree is: " + BTree->leftMost(rootNode)->data); Console::WriteLine("The value of the right-most node in this tree is: " + BTree->rightMost(rootNode)->data); Console::WriteLine("The size of this Binary Search Tree is: " + BTree->treeSize(rootNode)); Console::WriteLine("Printing Binary Search Tree in order: "); BTree->printTreeInOrder(rootNode); // TO EXAMINE THE PROPERTIES OF A GIVEN NODE, CHANGE THE SECOND PARAMETER OF // THE lookUp METHOD IN THE FOLLOWING LINE OF CODE TO THE NODE DESIRED TO BE EXAMINED BTree->printNodeMembers(BTree->lookUp(rootNode, 7)); Console::WriteLine(); return 0; }

最满意答案

比较运算符不可用于泛型。 没有定义它们的接口,与C ++模板不同,编译器不知道将使用的所有类型。

你想要的是IComparable<T> 。 此接口定义方法CompareTo(T) ,如果第一个对象分别小于,等于或大于另一个对象,则返回负数,零或正数。 (这可能有点难以记住,所以请记住: (x [symbol] y)变成(x.CompareTo(y) [symbol] 0) 。)

给定一般类型T ,您不知道T是否实际实现了IComparable<T> 。 你想要做的是强制编译器只允许实现IComparable<T> 。

generic <typename T> where T : IComparable<T> ref class Node { ... }; generic <typename T> where T : IComparable<T> ref class BinarySearchTreeClass { ... };

现在您可以在类中使用CompareTo方法:

if (node->data->CompareTo(key) < 0) return lookUp(node->right, key); else return lookUp(node->left, key);

其他一些小的语法问题:

generic <typename T> ref class Node<T> :不需要Node<T> ,只需要Node 。 Node类是通用的,因为generic <typename T> ,你也不需要<T> 。

Node<T>(){} :您不需要<T> 。 泛型类的构造函数已经是通用的,您无需再次指定它。

The comparison operators are not available for use with generics. There's no interface that defines them, and unlike C++ templates, the compiler doesn't know all the types that will be used.

The thing you want is IComparable<T>. This interface defines the method CompareTo(T), which will return a negative number, zero, or a positive number if the first object is less than, equal to, or greater than the other one, respectively. (That can be a little hard to remember, so remember this: (x [symbol] y) turns into (x.CompareTo(y) [symbol] 0).)

Given a general type T, you don't know whether T actually implements IComparable<T> or not. What you want to do is force the compiler to only allow classes that implement IComparable<T>.

generic <typename T> where T : IComparable<T> ref class Node { ... }; generic <typename T> where T : IComparable<T> ref class BinarySearchTreeClass { ... };

Now you can use the CompareTo method in your class:

if (node->data->CompareTo(key) < 0) return lookUp(node->right, key); else return lookUp(node->left, key);

A couple other minor syntax issues:

generic <typename T> ref class Node<T>: Don't need Node<T>, just Node. The Node class is generic already because of the generic <typename T>, you don't need the <T> as well.

Node<T>(){}: You don't need the <T>. The constructor of a generic class is already generic, you don't need to specify it again.

更多推荐

本文发布于:2023-07-25 05:41:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1256784.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:Learning   泛型   managed   closed   generics

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!