I tried to extend a listbox by adding a couple functions. I get an error ( error C2144: syntax error : 'Extended_ListBox' should be preceded by ':'). Would anyone please teach me how to fix it? I went to the line which VC++ said there was the error, but I had no clue why the constructor had an error.
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Collections;
using namespace System::Collections::Generic;
#include <stdio.h>
#include <stdlib.h>
#using <mscorlib.dll>
public ref class Extended_ListBox: public ListBox{
public Extended_ListBox(array<String ^> ^ textLineArray, int counter){
textLineArray_store = gcnew array<String ^>(counter);
for (int i=0; i<counter; i++){
this->Items->Add(textLineArray[i]);
textLineArray_store[i] = textLineArray[i];
}
this->FormattingEnabled = true;
this->Size = System::Drawing::Size(380, 225);
this->TabIndex = 0;
this->SelectedIndexChanged += gcnew System::EventHandler(this, &Extended_ListBox::listBox1_SelectedIndexChanged);
}
public Extended_ListBox(){
this->FormattingEnabled = true;
this->Size = System::Drawing::Size(380, 225);
this->TabIndex = 0;
this->SelectedIndexChanged += gcnew System::EventHandler(this, &Extended_ListBox::listBox1_SelectedIndexChanged);
}
private: System::Void listBox1_SelectedIndexChanged(System::Object^ sender, System::EventArgs^ e) {
int index=this->SelectedIndex;
tempstring = textLineArray_store[index];
}
private: array<String ^> ^ textLineArray_store;
private: String ^tempstring;
public: String ^GetSelectedString(){
return tempstring;
}
public: void ListBox_Update(array <String ^> ^ textLineArray, int counter){
textLineArray_store = gcnew array<String ^>(counter);
for (int i=0; i<counter; i++){
this->Items->Add(textLineArray[i]);
textLineArray_store[i] = textLineArray[i];
}
}
};
In C++/CLI, you specify the access modifier (public, private, etc.) differently than in, say, C# or Java.
Instead, you just write one line (note the colon, which is required):
public:
and all the following members are public. So insert that line before your constructors and remove the public keyword before the constructors. Like that:
public ref class Extended_ListBox: public ListBox{
public:
Extended_ListBox(array<String ^> ^ textLineArray, int counter){
// constructor code
}
Extended_ListBox(){
// default constructor code
}
// other public members
// ...
private:
// private members
// ...
}
Similar to the members below the constructors in your current example, except that you don't have to explicitly restate public: or private: if the next member has the same visibility.
Related
I'm trying to declare a friend function of a class with static members. I compiled my program in Visual Studio 2017 and faced this compile-time error:
unresolved external symbol "private: static struct Number * user::Link" (?Link#user##0PAUNumber##A)
Here's my code:
#include<iostream>
using namespace std;
typedef struct Number
{
int number;
struct Number *Link;
}
num_t;
class user
{
private:
static num_t *Link;
static int Length;
public:
static void Create()
{
cout << "You called a function." << endl;
Link->number = 1;
}
friend void Show_menu();
};
void Show_menu()
{
user::Create();
}
int user::Length = 1;
num_t user::*Link = nullptr;
int main()
{
return 0;
}
Generally, Is it possible to define a friend function of a class with static members in C++? If so, how do I fix the problem above?
I think you wanted num_t* user::Link = nullptr;.
The error has nothing to do with the declared friend.
I've been assigned to write a class "binaryExpressionTree" which is derived from the abstract template class "binaryTreeType." binaryExpressionTree is of type String. As part of the assignment, I have to override these 3 virtual functions from binaryTreeType:
//Header File Binary Search Tree
#ifndef H_binaryTree
#define H_binaryTree
#include <iostream>
using namespace std;
//Definition of the Node
template <class elemType>
struct nodeType
{
elemType info;
nodeType<elemType> *lLink;
nodeType<elemType> *rLink;
};
//Definition of the class
template <class elemType>
class binaryTreeType
{
public:
virtual bool search(const elemType& searchItem) const = 0;
virtual void insert(const elemType& insertItem) = 0;
virtual void deleteNode(const elemType& deleteItem) = 0;
binaryTreeType();
//Default constructor
};
binaryTreeType<elemType>::binaryTreeType()
{
}
#endif
Here is what I have so far for binaryExpressionTree:
#define EXPRESSIONTREE_H
#include "binaryTree.h"
#include <iostream>
#include <string>
class binaryExpressionTree : public binaryTreeType<string> {
public:
void buildExpressionTree(string buildExpression);
double evaluateExpressionTree();
bool search(const string& searchItem) const = 0;
void insert(const string& insertItem) = 0;
void deleteNode(const string& deleteItem) = 0;
};
And here's binaryExpressionTree.cpp:
#include <string>
#include <cstring>
#include <stack>
#include <cstdlib>
#include <cctype>
#include "binaryExpressionTree.h"
#include "binaryTree.h"
using namespace std;
bool binaryExpressionTree::search(const string& searchItem) const {
return false;
}
void binaryExpressionTree::insert(const string& insertItem) {
cout << "this";
}
void binaryExpressionTree::deleteNode(const string& deleteItem) {
cout << "this";
}
Here's main.cpp:
#include <iostream>
#include <iomanip>
#include <fstream>
#include "binaryExpressionTree.h"
int main()
{
binaryExpressionTree mainTree = binaryExpressionTree(); //Error:[cquery] allocating an object of abstract class type 'binaryExpressionTree'
return 0;
}
The problem is, since binaryExpressionTree is a derived class of type String, it doesn't know what "elemType" means and I would need to change searchItem, insertItem and deleteItem
to string& objects. But once I do, the compiler no longer recognizes that I am overriding virtual functions (as I've changed their parameters), and declares binaryExpressionTree to be an abstract class. How do I work around this, so that I can override the functions and make binaryExpressionTree non-abstract?
Assuming the abstract class is defined like this:
template <typename elemType>
class binaryTreeType { ... }
You should define your class as follows:
class binaryExpressionTree : public binaryTreeType<String> { ... }
EDIT: original question was edited.
You are incorrectly declaring the overriding functions (inside binaryExpressionTree).
Your declaration is like this:
bool search(const string& searchItem) const = 0;
Such declaration creates a pure virtual method (because of = 0 at the end of the declaration. A pure virtual method (aka an abstract method) is a method which must be overridden by a deriving class. Thus, binaryTreeType declared its methods pure virtual, in order for you to implement, in binaryExpressionTree.
Classes which have abstract methods which are not implemented yet, cannot be instantiated - that is the error your compiler is generating.
Instead, you should declare your methods like this:
virtual bool search(const elemType& searchItem) const;
Such declaration creates regular virtual function, which would override the parent implementation (which is non-existent, at this case).
TL;DR - remove = 0.
I have the following code in io.h:
#include <iostream>
#include "shape.h"
class IODevice { // Interface for displaying CAD objects
public:
virtual void operator << (const Circle& c) = 0;
virtual void operator << (const Line& c) = 0;
};
class CmdIODevice : public IODevice {
void operator << (const Circle& c);
void operator << (const Line& c);
};
and shape.h :
#pragma once
#include "io.h"
class Shape {
public:
virtual void display(IODevice& ioDevice) = 0;
};
class Circle : public Shape {
public:
void display(IODevice& ioDevice);
};
class Line : public Shape {
public:
void display(IODevice& ioDevice);
}
};
and get the following error when I declare the virtual operator in IODevice:
Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int
Apparently Circle is not seen by the compiler, I do not understand, please help.
Hello Dear Community of SO!
I have a following problem - I wrote a simple add_record function using structures (here is my main file):
// Exercise1.cpp : main project file.
#include "stdafx.h"
#include "Form1.h"
using namespace Exercise1;
typedef struct student {
char *name;
int index;
double avg;
student *next;
student *prev;
} stud;
student *first = 0;
[STAThreadAttribute]
void add_record(student **first, char *name, int index, double avg){
student *new_stud = new student;
if (*first!=0) (*first)->prev = new_stud;
new_stud->name = name;
new_stud->avg = avg;
new_stud->index = index;
new_stud->next = *first;
new_stud->prev = 0;
*first = new_stud;
}
However, I can't put this add record function into button action (with predefined data, just for testing purposes)
Code for Form1.h:
#pragma once
namespace Exercise1 {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for Form1
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Button^ button1;
protected:
private: System::Windows::Forms::Button^ button2;
//all remaining buttons here - irrelevant
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
}
#pragma endregion
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
String ^ i = "working";
textBox1->Text = i;
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
String ^ g = "test";
if(add_record(student **first, testname, 23, 3.5))
textBox1->Text = g;
}
};
}
How to fix that part with record adding?
I get a following error:
1>d:\visual studio 2010 express\projects\exercise1\exercise1\Form1.h(176): error C2065: 'student' : undeclared identifier
1>d:\visual studio 2010 express\projects\exercise1\exercise1\Form1.h(176): error C2065: 'first' : undeclared identifier
1>d:\visual studio 2010 express\projects\exercise1\exercise1\Form1.h(176): error C2065: 'testname' : undeclared identifier
1>d:\visual studio 2010 express\projects\exercise1\exercise1\Form1.h(176): error C3861: 'add_record': identifier not found
I guess it's something connected with variable declaration but I don't know where to put that in order for it to work..
Thanks in advance
From your code snippet.
There is no type defined as student - the struct is typdef to stud - this explains why the compiler yells at you it doesn't recognize the student **first argument type in the add_record method declaration.
using namespace Exercise1;
typedef struct student {
char *name;
int index;
double avg;
student *next;
student *prev;
} stud; // <<<-------------------- should it be "} student;"?
student *first = 0;
[STAThreadAttribute]
void add_record(student **first, char *name, int index, double avg){
student *new_stud = new student;
if (*first!=0) (*first)->prev = new_stud;
new_stud->name = name;
new_stud->avg = avg;
...
#include "Calc.h"
#include<iostream>
#include <windows.h>
#include <WINERROR.H.>
typedef void (WINAPI * PCTOR) ();
int main()
{
HMODULE hMod = LoadLibrary (L"Calci.dll");
if (NULL == hMod)
{
printf ("LoadLibrary failed\n");
return 1;
}
CCalc *pCCalc = (CCalc *) malloc (sizeof (CCalc));
if (NULL == pCCalc)
{
printf ("memory allocation failed\n");
return 1;
}
PCTOR pCtor = (PCTOR) GetProcAddress (hMod, "CCalc");//127 error
int err = GetLastError();
if (NULL == pCtor)
{
printf ("GetProcAddress failed\n");
return 1;
}
__asm { MOV ECX, pCCalc };
pCtor ();
return 0;
}
//dll file
#include <tchar.h>
#ifdef CALC_EXPORTS
#define CALC_API __declspec (dllexport)
#else
#define CALC_API __declspec (dllimport)
#endif
#define SOME_INSTN_BUF 260
class CALC_API CCalc
{
private:
char m_szLastUsedFunc[SOME_INSTN_BUF];
public:
CCalc ();
int Add (int i, int j);
int Sub (int i, int j);
TCHAR* GetLastUsedFunc ();
};
Use dumpbin.exe to check the exact name of the export in the DLL. Maybe it doesn't exist at all?
If you have a chance to use import library instead of LoadLibrary API, it is better.
You're invoking GetProcAddress (hMod, "CCalc"), however "CCalc" isn't the name of a function: it's the name of a class.
You're trying to load the address of the CCalc::CCalc default constructor: to do that, use a tool (e.g. dumpbin) to discover the "decorated" name of the constructor.
However instead of trying to dynamic-load and invoke the constructor, a more usual way to implement this functionality would be to create a static factory method in the DLL, e.g. like this:
class CALC_API CCalc
{
public:
static CCalc* create() { return new CCalc(); }
private:
//doesn't need to be public because users instantiate this class using
//the static create method
CCalc();
public:
virtual int Add (int i, int j);
virtual int Sub (int i, int j);
virtual TCHAR* GetLastUsedFunc ();
virtual ~CCalc() {}
};
Then use GetProcAddress to get the address of the static CCalc::create function, which because it's static you can invoke without using assembly to mess with ECX.
You can't use GetProcAddress for classes. This does not work. Only functions you can resolve their names are unmangled "C" functions.
For example:
extern "C" __declspec(dllexport) CCalc *create_calc()
{
return new CCalc;
}
Now, you can resolve it using.
GetProcAddress(halnder,"create_calc");
As create_calc is not-mangled function.
Also you will have to provide abstract API class without implementation and make CCalc inherit ACalc, otherwise you'll get unresolved symbols tying to compile your application. Because actual add and remove member functions are not known to the application.
class ACalc {
public:
virtual add(int i,int j) = 0;
...
virtaul ~ACalc() {}
};
class CCalc : public ACalc {
public:
virtual add(int i,int j) { ... };
...
};
And in the main program
ACalc *ptr= call_for_dll_function