c++ Syntax help

  • (2 Pages)
  • +
  • 1
  • 2

16 Replies - 710 Views - Last Post: 02 November 2020 - 08:47 PM Rate Topic: -----

#1 fearfulsc2   User is offline

  • D.I.C Regular

Reputation: 19
  • View blog
  • Posts: 342
  • Joined: 25-May 16

c++ Syntax help

Posted 27 October 2020 - 07:21 PM

Hi everyone, I am really rusty in C++ but come from a C# background. I am trying to figure out how to implement the testThread portion of the UML and I am having a little bit of issue with how to implement it.
Image

Header File
#ifndef TESTTHREAD_H
#define TESTTHREAD_H
#include <functional>
#include <vector>
#include <sstream>
#include <iostream>
#include <itest.h>
#include <outputStream.h>
#include <logMessage.h>

class TestThread : public Itest
{
public:
	TestThread(); // Constructor
	TestThread(Itest*()); // overloaded constructor

	virtual ~TestThread(); // Destructor
	bool execTest();
private:
	bool LogResult(tht::logMessage msg);
	bool LogException(tht::logMessage msg);
	Itest* _executor;
	//Itest* TestFunction();
	Itest::TestResult executeTest();
	tht::outputStream* outputStream;
};


There are bits and pieces that are probably not needed.

In the .cpp file, I am struggling a bit. The idea is that we are supposed to take in a function and execute it in our try/catch block and output the result. I am struggling with being able to pass in a function to the class and execute it. Any insights I can look at?
#include <TestThread.h>

TestThread::TestThread() {
}

TestThread::TestThread(Itest* ())
{
}

TestThread::~TestThread() {}

bool TestThread::LogResult(tht::logMessage msg)
{
	msg.setMsgText("RUNNING");
	return true;
}

bool TestThread::execTest() 
{
	try 
	{
		return true;
	}
	catch (_exception e)
	{
		return false;
	}
}

bool TestThread::LogException(tht::logMessage msg) 
{
	return true;
}

Itest::TestResult TestThread::executeTest()
{
	try
	{
		return TestResult(0);
	}
	catch (_exception e)
	{
		return TestResult(2);
	}

}


This post has been edited by fearfulsc2: 27 October 2020 - 07:38 PM


Is This A Good Question/Topic? 0
  • +

Replies To: c++ Syntax help

#2 jimblumberg   User is offline

  • member icon

Reputation: 5882
  • View blog
  • Posts: 17,877
  • Joined: 25-December 09

Re: c++ Syntax help

Posted 28 October 2020 - 07:23 AM

Quote

There are bits and pieces that are probably not needed.

Actually you're not providing enough code. For example what is an Itest? What is tht? I suggest you post the complete program.

Do you know that in C++ everything doesn't need to be part of a class?

You have methods that don't do anything, why? For example your constructors and destructor aren't doing anything, so are they even needed?

Quote

I am struggling with being able to pass in a function to the class and execute it.

This question is quite vague, please explain what you mean by "pass a function to the class"?

Jim

Edit: I would also be helpful if you posted the actual assignment and explain your XML diagram.

This post has been edited by jimblumberg: 28 October 2020 - 07:25 AM

Was This Post Helpful? 0
  • +
  • -

#3 fearfulsc2   User is offline

  • D.I.C Regular

Reputation: 19
  • View blog
  • Posts: 342
  • Joined: 25-May 16

Re: c++ Syntax help

Posted 28 October 2020 - 12:23 PM

This is the Itest class. It's supposed to be an interface
#ifndef ITEST_H_
#define ITEST_H_

#include <functional>
#include <iostream>
#include <string>

class Itest
{
public:

    enum class TestResult{PASS,FAIL, EXCEPTION};
    
    // getStringResult - returns the a string representation of TestResult enum type.
    // Param result - a TestResult enum type {PASS,FAIL,EXCEPTION}
    static std::string getStringResult(TestResult result);    
    
    // Pure virtual function TestResult
    // Param executor - has to be a lambda object which returns an int type.
    virtual TestResult executeTest(std::function<int()> executor) = 0;
    
    // Virtual Destructor
    virtual ~Itest() = default;

    // New virtual functions here which can be specialized ..
};

#endif 


We are trying to implement a TestHarness. I am supposed to accept any function and execute it and return a pass/failure from within the try/catch block.

In this case, I do not need a default constructor but I would need a Constructor with a pointer to Itest being passed in according to the block diagram.

I'm not too familiar with the syntax for the testThread class
Was This Post Helpful? 0
  • +
  • -

#4 random Goose   User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 101
  • Joined: 07-August 20

Re: c++ Syntax help

Posted 28 October 2020 - 05:39 PM

Quote

supposed to accept any function

I'm not sure if this is even possible in C ++. Any function? Or any function of the same "type" (parameters\return values in all possible defined functions will be the same).

This post has been edited by random Goose: 28 October 2020 - 05:41 PM

Was This Post Helpful? 0
  • +
  • -

#5 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7575
  • View blog
  • Posts: 25,496
  • Joined: 05-May 12

Re: c++ Syntax help

Posted 28 October 2020 - 05:43 PM

The issue here seems to be the misuse of the term "test function". Itest is an "test interface". Conceptually, it may be a wrapper for a "test function" but for us just reading the code and not fully versed in your problem domain, it just looks like a "test interface".

Anyway, this looks wrong:
TestThread(Itest*());



If TestThread takes a "test interface", then the constructor signature should look something like:
TestThread(Itest * itest);


Was This Post Helpful? 0
  • +
  • -

#6 fearfulsc2   User is offline

  • D.I.C Regular

Reputation: 19
  • View blog
  • Posts: 342
  • Joined: 25-May 16

Re: c++ Syntax help

Posted 28 October 2020 - 08:03 PM

From my understanding, we are supposed to have an "executor method" that accepts any callable object that accepts no arguments and returns a bool to indicate success or failure.

In that executor method, we are to invoke the passed callable object in a try/catch block.

That is why we have the execTest method as a public boolean.

Aside from that, I am not sure how to properly do that in a syntactically correct way.

What I have in the header file is this
class TestThread : public Itest
{
public:
	TestThread(Itest* itest); // maybe I need to have another parameter here?
	virtual ~TestThread();
	bool execTest();
private:
	bool LogResult(tht::logMessage msg);
	bool LogException(tht::logMessage msg);
	Itest::TestResult executeTest();
	Itest* testFunction;
};



Now in the .cpp file, I have this but I am still far off
#include <TestThread.h>

TestThread::TestThread(Itest* itest) // maybe I'll need another parameter here to take in a callable method?
{
	testFunction = itest;
}

TestThread::~TestThread() {}

bool TestThread::LogResult(tht::logMessage msg)
{
	msg.setMsgText("RUNNING");
	return true;
}

bool TestThread::execTest() 
{
	try 
	{
                // I want to do something like 
                // testFunction->executeTest(BUT I DO NOT KNOW WHAT TO PUT HERE)
		return true;
	}
	catch (_exception e)
	{
		return false;
	}
}

bool TestThread::LogException(tht::logMessage msg) 
{
	return true;
}



The ITest Header looks like this
class Itest
{
public:

    enum class TestResult{PASS,FAIL, EXCEPTION};
    
    // getStringResult - returns the a string representation of TestResult enum type.
    // Param result - a TestResult enum type {PASS,FAIL,EXCEPTION}
    static std::string getStringResult(TestResult result);    
    
    // Pure virtual function TestResult
    // Param executor - has to be a lambda object which returns an int type.
    virtual TestResult executeTest(std::function<int()> executor) = 0;
    
    // Virtual Destructor
    virtual ~Itest() = default;

    // New virtual functions here which can be specialized ..
};


Was This Post Helpful? 0
  • +
  • -

#7 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7575
  • View blog
  • Posts: 25,496
  • Joined: 05-May 12

Re: c++ Syntax help

Posted 29 October 2020 - 05:49 AM

Your UML didn't show the TestThread as owning a executor : std::function<int()> (either via an attribute or through composition/aggregation). If the TestThread is supposed to hold the std::function, then add it a class variable, and also as a constructor parameter.

Personally, I feel like your Itest has been incorrectly designed if the caller needs to pass in what to test. So what does the interface really do then?

I would have expected the interface's executeTest() not to take any parameters, and that a concrete class that implements the interface would either implement a test within executeTest(), or a wrapper class that implements the interface would take a std::function and be the one to invoke the lambda when executeTest() is called.
Was This Post Helpful? 0
  • +
  • -

#8 fearfulsc2   User is offline

  • D.I.C Regular

Reputation: 19
  • View blog
  • Posts: 342
  • Joined: 25-May 16

Re: c++ Syntax help

Posted 29 October 2020 - 01:09 PM

The UML diagram shows that the thtExecutor class will invoke the testThread class.

From what I am understanding from the diagram, the thtExecutor class will be creating a new thread (irrelevant for what I am asking at the moment) and then calling testThread with a function to execute. thtExecutor will be telling testThread which function to execute. In testThread, that function will be executed from within a try/catch block and will return a boolean of whether the function executed to completion or an exception was thrown at some point.

I think that is why we have a pointer to the Itest interface because that interface is supposed to execute some function via a lambda expression.

So I have been trying to figure out how to accept that in testThread somewhere so that I can invoke/execute that random function.

Does that make sense or am I being confusing?
Was This Post Helpful? 0
  • +
  • -

#9 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7575
  • View blog
  • Posts: 25,496
  • Joined: 05-May 12

Re: c++ Syntax help

Posted 29 October 2020 - 04:00 PM

Yes, but how where does TestThread::execTest() get the lambda that is passed in to testFunction->executeTest()?

It's why in your comments you have the question "BUT I DO NOT KNOW WHAT TO PUT HERE". It's because you don't have a std:function to that you are holding on to to pass in.

You could hard code lambda in there, but then that means you need to implement a concrete TestThread class for every kind of test that you want to implement. This is why I think there was some kind of design error. I believe that the intent of the Itest as an interface was so that there would be multiple concrete classes that implement Itest, and for the cases when the only thing that varies is the test function body, then a version of a concrete class that implements Itest would just take a lambda as a parameter.
Was This Post Helpful? 0
  • +
  • -

#10 fearfulsc2   User is offline

  • D.I.C Regular

Reputation: 19
  • View blog
  • Posts: 342
  • Joined: 25-May 16

Re: c++ Syntax help

Posted 29 October 2020 - 07:09 PM

I tried doing this as a test but it is throwing MANY exceptions.

Main.cpp
Itest* test{};
TestThread t(test);
t.execTest();



bool TestThread::execTest() 
{
	try 
	{
		//int res = Itest::executeTest(somethingrandom);
		testFunction->executeTest(somethingrandom);
		return true;
	}
	catch(std::exception & e)
	{
		return false;
	}
}

std::function<int()> somethingrandom()
{
	return 0;
}



This is the allocation that I get when I try to do Itest* test{};
0x0000000000000000

However, I am not able to do anything else. So I am doing this all wrong I would think.
Was This Post Helpful? 0
  • +
  • -

#11 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7575
  • View blog
  • Posts: 25,496
  • Joined: 05-May 12

Re: c++ Syntax help

Posted 30 October 2020 - 06:45 AM

This line:
Itest* test{};



Is the equivalent to:
Itest* test = nullptr;



So you are passing in a null pointer to your TestThread's constructor. Later you just blindly dereference that pointer.
Was This Post Helpful? 1
  • +
  • -

#12 fearfulsc2   User is offline

  • D.I.C Regular

Reputation: 19
  • View blog
  • Posts: 342
  • Joined: 25-May 16

Re: c++ Syntax help

Posted 30 October 2020 - 09:35 AM

I got a little closer.

I was able to do something like this in my header
class TestThread : Itest
{
public:
	TestThread();
	TestThread(Itest* itest);
	virtual ~TestThread();
	bool execTest();

	// executeTest will have a lambda function inside
	// which will return a random Itest::TestResult type
	[b]virtual TestResult executeTest(std::function<int()> executor);
	std::function<int()> somethingrandom();[/b]
private:
	bool LogResult(tht::logMessage msg);
	bool LogException(tht::logMessage msg);
	Itest* testFunction;
};



And then in my cpp file I was able to do this
TestThread::TestThread(Itest* itest)
{
	testFunction = itest;
}

TestThread::~TestThread() {}

bool TestThread::LogResult(tht::logMessage msg)
{
	msg.setMsgText("RUNNING");
	return true;
}

bool TestThread::execTest() 
{
	try 
	{
		TestRandom random;
		//TestFunction->getStringResult(random.getFinalResult());
		//int res = Itest::executeTest(somethingrandom);
		executeTest(somethingrandom());
		//testFunction->executeTest(somethingrandom);
		return true;
	}
	catch(std::exception & e)
	{
		return false;
	}
}

bool TestThread::LogException(tht::logMessage msg) 
{
	return true;
}

Itest::TestResult TestThread::executeTest(std::function<int()> executor)
{
	int output = executor();
	return TestResult::PASS;
}

[b]std::function<int()> TestThread::somethingrandom()[/b]
{
	return []() {
		return 1;
	};
}



I guess the thing is how can I accept that function as a parameter so that I can execute it in that way?
Was This Post Helpful? 0
  • +
  • -

#13 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7575
  • View blog
  • Posts: 25,496
  • Joined: 05-May 12

Re: c++ Syntax help

Posted 30 October 2020 - 10:19 AM

See post #7, first sentence.
Was This Post Helpful? 0
  • +
  • -

#14 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7575
  • View blog
  • Posts: 25,496
  • Joined: 05-May 12

Re: c++ Syntax help

Posted 31 October 2020 - 07:37 AM

Now that I'm reading this thread on a PC instead of on my phone and I don't have to keep scrolling around, I see that I missed something major. Your TestThread implements the Itest interface as per this line:
class TestThread : Itest


This means that you have a IS-A relationship, not a HAS-A relationship. Therefore, there is no need for your TestThread class to have a Itest class variable (unless you also happen to be trying to implement the Decorator pattern, but I'm not seeing that in your UML diagram). Therefore you don't really need this constructor:
TestThread(Itest* itest);



The constructor that you should actually have should be:
TestThread(std::function<int()> executor);


and you need to update your diagrams and code to show that TestThread HAS-A std::function<int()> executor.
Was This Post Helpful? 0
  • +
  • -

#15 fearfulsc2   User is offline

  • D.I.C Regular

Reputation: 19
  • View blog
  • Posts: 342
  • Joined: 25-May 16

Re: c++ Syntax help

Posted 01 November 2020 - 01:33 PM

What I changed it to was this

Header
class TestThread : Itest
{
public:
	TestThread(std::function<int()> executor);
	virtual ~TestThread();
	bool execTest();

	// executeTest will have a lambda function inside
	// which will return a random Itest::TestResult type
	virtual TestResult executeTest(std::function<int()> executor);
private:
	bool LogResult(tht::logMessage msg);
	bool LogException(tht::logMessage msg);
	std::function<int()> execute;
};



.cpp, it appears that that when I throw, the catch isn't working?
TestThread::TestThread(std::function<int()> executor)
{
	execute = executor;
}

TestThread::~TestThread() {}

bool TestThread::LogResult(tht::logMessage msg)
{
	std::cout << msg.getMsgText() << std::endl;
	return true;
}

bool TestThread::execTest() 
{
	tht::logMessage msg;
	try 
	{
		msg.setMsgText("Logging Start");
		LogResult(msg);
		TestResult result = executeTest(execute);
		if (result == TestResult::PASS)
			msg.TESTPASS;
		else if (result == TestResult::FAIL)
			msg.TESTFAIL;
		msg.setMsgText("Logging End");
		LogResult(msg);
		return true;
	}
	catch(std::exception & e) // doesn't appear to be catching the exception?
	{
		msg.setMsgText(e.what());
		msg.EXCEPTION;
		msg.setExceptionType("Exception");
		msg.setMsgText("Logging End");
		LogException(msg);
		return false;
	}
}

bool TestThread::LogException(tht::logMessage msg) 
{
	std::cout << msg.getMsgText() << std::endl;
	return true;
}

Itest::TestResult TestThread::executeTest(std::function<int()> executor)
{
	int output = executor();
	if (output == 1)
		return TestResult::PASS;
	else if (output == 2)
		return TestResult::FAIL;
	else
		throw;
}



Main.cpp
TestRandom random;
TestThread t(random.returnResult()); // this function gets called here and also when my TestThread.cpp class executes it. Not sure how to make it run only once in the TestThread class
t.execTest(); // the random.returnResult() will run again in here.



testRandom.cpp
std::function<int()> TestRandom::returnResult() // testing purposes only
{
    srand(static_cast<unsigned int> (time(0)));
    return [] () { 
        return (1 + rand() % 3);
        };
}


Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2