class member functions with pointer parameters - class

I have this homework assignment that is giving me a lot of trouble right now. My teacher is very vague in class and hard to communicate with. I will try very hard to articulate my thoughts here.
Here is the assignment:
(3pts) Given the following class header file, write the class’ source
code for each of the accessor and mutator functions listed. (Pay
attention to how the functions have listed their parameters, varying
between passing by reference and by value.) Don’t forget to comment
your code – it counts!
class Album {
private:
char * artist; // band or singer’s name
char * title; // title of the album
int year_released; // year the album is released
char * record_label; // name of company produced album
int num_songs; // number of songs on the album
int num_minutes_long; // length (mins) of album
char * genre; // genre of artist (eg, rock, pop, …)
public:
//constructors
Album();
Album(char *& a, char *& t);
//deconstructor
~Album();
//accessors and mutators
bool set_artist(char * a);
bool set_title(char * t);
bool set_year_released(int value);
bool set_record_label(char *& label);
bool set_num_songs(int value);
bool set_num_minutes_long(int value);
bool set_genre(char * g);
bool get_artist(char *& a);
bool get_title(char *& t);
int get_year_released();
bool get_record_label(char *& label);
int get_num_songs();
int get_num_minutes_long();
bool get_genre(char *& g);
};
Here is my work so far:
bool Album::set_artist(char * a)
{
*artist = a;
}
bool Album::set_title(char * t)
{
*title = t;
}
bool Album::set_year_released(int value)
{
year_released = value;
}
bool Album::set_record_label (char *& label)
{
*record_label = label;
}
bool Album::set_num_songs(int value)
{
num_songs = value;
}
bool Album::set_number_minutes_long(int value)
{
num_minutes_long = value;
}
bool Album::set_genre(char * g)
{
*genre = g;
}
bool Album::get_artist(char *& a)
{
return artist;
}
bool Album::get_title(char *& t)
{
return title;
}
int Album::get_year_released()
{
return year_released;
}
bool Album::get_record_label(char *& label)
{
return *record_label;
}
The input will be an array.
My questions:
First, am I on the right track?
When using (char * a) for a function, for example, this is passing the address of a, correct? so then *artist=a; changes what the address of a points to?
Also, the functions are bool when I would expect void. Why?
For all of the set_xxx functions, the parameter is *... but for set_record_label it is *&. That appears to be a mistake to me. Is that right?
What is the difference between *& and * as parameters?
Thank you for your time. I know there is a lot here.

First, am I on the right track?
A bit to general , let's go into details. But at least, you did not provide the required comments.
When using (char * a) for a function, for example, this is passing the address of a, correct?
No. It passes an address called a.
so then *artist=a; changes what the address of a points to?
This produces a type mismatch. artist is a pointer to char. *artist is the char variable artist points to. a is, agian, a pointer to char. So, you assign a pointer to a char variable => type mismatch.
Also, the functions are bool when I would expect void. Why?
I have no idea why do you expect void. However, bool makes sense: It allows the function to report, whether the operation (with side effect!) was successful or not.
For all of the set_xxx functions, the parameter is * ... but for
set_record_label it is *&. That appears to be a mistake to me. Is
that right?
Since your instructor stresses the use of different parameters, it is probably no error. However, in real life it would be a bad style.
What is the difference between *& and * as parameters?
* describes a pointer, & a reference. The referenced value can be a pointer again. I suggest that you reread the section on types in your textbook.

Related

How structs are extended just importing packages in D?

I have this fibonacci number generator.
struct FibonacciSeries
{
int first = 0;
int second = 1;
enum empty = false;
#property int front() const
{
return first;
}
void popFront()
{
int third = first + second;
first = second;
second = third;
}
#property FibonacciSeries save() const
{
return this;
}
}
This struct does not have the take method, so I have this error when executing this command (writeln(FibonacciSeries().take(5))).
a.d(66): Error: no property 'take' for type 'FibonacciSeries'
However, by importing range package, it has the take method. What's the mechanism behind this?
The mechanism is Uniform Function Call Syntax:
http://dlang.org/function.html#pseudo-member
To put it simply, if a.foo(b...) is not valid, the compiler tries rewriting it to foo(a, b...).

How to use references and pointers in c++ classes?

i have the following problem: I am using an existing class which creates an object called server_t.
Another function expects *server_t as an argument.
I wanted to shrink the code and added a class which has following members:
#ifndef _PMCLASS
#define _PMCLASS
#include "pmlib.h"
class pmServer{
private:
server_t server ;
counter_t counter;
line_t lines;
server_t * server2;
int set, frequency, aggregate ;
public:
pmServer();
pmServer(int set, int frequency, int aggregate);
~pmServer();
void setSet(int s);
void setFrequency(int f);
void setAggregate(int a);
int getSet(void);
int getFrequency(void);
int getAggregate(void);
server_t* getServerT(void);
counter_t* getCounterT(void);
line_t* getLineT(void);
server_t* getZeiger(void);
};
#endif
then i created the constructors:
#include "pmClass.h"
#include <iostream>
using namespace std;
void pmServer::setSet(int s){
this->set = s;
}
void pmServer::setFrequency(int f){
this->frequency = f;
}
void pmServer::setAggregate(int a){
this->aggregate = a;
}
int pmServer::getSet(void){
return set;
}
int pmServer::getFrequency(void){
return frequency;
}
int pmServer::getAggregate(void){
return aggregate;
}
server_t* pmServer::getPointer(){
return &server;
}
pmServer::pmServer(){
set = -1;
frequency = 0;
aggregate = 1;
}
then i tried to create an object ->worked, but then i wanted to use the pm_set_server(...)
it wants following arguments: int pm_set_server( char *ip, int port, server_t *pm_server)
void run() {
build_initial_mesh();
// Construct / read in the initial mesh.
pmServer server1;
pm_set_server("xxx.xxx.xxx.xxx", 6526,server1.getPointer); //its a correct ip address , no panic :)
i got that:
error: argument of type 'server_t*' (pmServer::)() does not match 'server_t*'
but this worked without any problems:
void run() {
// Construct / read in the initial mesh.
//pmServer server1;
server_t test;
pm_set_server("xxx.xxx.xxx.xxx", 6526,&test);
build_initial_mesh();
The thing is, i didn't want to create everytime new ojects and wanted to do that in the constructor...Does somebody have any idea?
thanks.
greetings Thomas
In C++, function calls need brackets*:
pm_set_server("xxx.xxx.xxx.xxx", 6526,server1.getPointer());
*exceptions apply, for operators.

error C2664 due to cdecl and myclass conflict

I'm trying to join an old piece of code in C to my present VC++ project:
// .h
class DMSinv : public CDialog {
double finte(double z);
double ITFStolz(double Zp1, double Zp2, double Zc);
};
// .cpp
double Zcglob;
double DMSinv::finte(double z)
{
return TFStolz(z, Zcglob);
}
double DMSinv::ITFStolz(double Zp1, double Zp2, double Zc)
{
int ierr;
Zcglob = Zc;
return (coteglob(&DMSinv::finte, Zp1, Zp2, 1.0e-10, &ierr));
//error C2664: 'DMSinv::coteglob' : cannot convert parameter 1 from 'double (__thiscall DMSinv::* )(double)' to 'double (__cdecl *)(double)'
}
the coteglob function comes from the old C part, and finte is a intermediate function to pass the TFStolz function to coteglob.
I've searched in the forums and found this related question:
How to convert void (__thiscall MyClass::* )(void *) to void (__cdecl *)(void *) pointer
which I tried to apply in this way:
// .h
class DMSinv : public CDialog {
virtual double finte(double z);
double ITFStolz(double Zp1, double Zp2, double Zc);
};
// .cpp
double Zcglob;
extern "C"
{
static double __cdecl finteHelper(double z)
{
DMSinv* datainv = reinterpret_cast< DMSinv > (z); //error C2440: 'reinterpret_cast' : cannot convert from 'double' to 'DMSinv'
datainv->finte(z);
}
}
double DMSinv::ITFStolz(double Zp1, double Zp2, double Zc)
{
int ierr;
Zcglob = Zc;
double solution = coteglob(&finteHelper, Zp1, Zp2, 1.0e-10, &ierr);
return solution;
}
but is still not working. Can somebody guide me on how to adapt it? I'm quite a newbie yet and this seems far from my knowledge.
Thanks in advance!
Not sure it is possible to do as you want. Only option that comes to my mind is to use some static variable to store address of DMSinv object. This limits you to 1 thread with simple implementation...
Try this:
// .h
class DMSinv : public CDialog {
double finte(double z);
double ITFStolz(double Zp1, double Zp2, double Zc);
private:
static DMSinv* _current;
static double __cdecl finteHelper(double z);
};
// .cpp
double Zcglob;
DMSinv* DMSinv::_current = 0;
double DMSinv::finte(double z)
{
return TFStolz(z, Zcglob);
}
double DMSinv::ITFStolz(double Zp1, double Zp2, double Zc)
{
int ierr;
Zcglob = Zc;
_current = this;
return (coteglob(DMSinv::finteHelper, Zp1, Zp2, 1.0e-10, &ierr));
}
double __cdecl DMSinv::finteHelper(double z)
{
return _current->finte(z);
}
This is not good solution IMO, but I'm not sure that there is other way.
PS
To remove limit of one thread you can use TLS slots or in VC++ just __declspec(thread).
With latter just add __declspec(thread) to _current like this: static __declspec(thread) DMSinv* _current;. BUT!!! be aware of that number of per-thread variables is limited for process. Read more on this in MSDN.
UPDATE
Disclamer: Just for fun.
Theoretically, there is other opportunity. You can store assembly code in array, attached to object. This assembly code should be a __cdecl function that simply translates __cdecl to __thiscall based on eip register. But this should never be done though... :D
I don't think you can do it this way. You need to somehow pass the reference to your object (this). In the linked question the parameter to the function was defined as type void * thus you could pass whatever you need to the function, including pointer to this. Your function accepts double, so you can't pass this to it.
I think the easiest would be to define your intermediate function out of class, since it appears to be independent of class internals. Something like this:
double finte(double z)
{
return TFStolz(z, Zcglob);
}
You can also store the instance pointer in a public global/static in-class variable that the static function can read.

What are function typedefs / function-type aliases in Dart?

I have read the description, and I understand that it is a function-type alias.
A typedef, or function-type alias, gives a function type a name that you can use when declaring fields and return types. A typedef retains type information when a function type is assigned to a variable.
http://www.dartlang.org/docs/spec/latest/dart-language-specification.html#kix.yyd520hand9j
But how do I use it? Why declaring fields with a function-type? When do I use it? What problem does it solve?
I think I need one or two real code examples.
A common usage pattern of typedef in Dart is defining a callback interface. For example:
typedef void LoggerOutputFunction(String msg);
class Logger {
LoggerOutputFunction out;
Logger() {
out = print;
}
void log(String msg) {
out(msg);
}
}
void timestampLoggerOutputFunction(String msg) {
String timeStamp = new Date.now().toString();
print('${timeStamp}: $msg');
}
void main() {
Logger l = new Logger();
l.log('Hello World');
l.out = timestampLoggerOutputFunction;
l.log('Hello World');
}
Running the above sample yields the following output:
Hello World
2012-09-22 10:19:15.139: Hello World
The typedef line says that LoggerOutputFunction takes a String parameter and returns void.
timestampLoggerOutputFunction matches that definition and thus can be assigned to the out field.
Let me know if you need another example.
Dart 1.24 introduces a new typedef syntax to also support generic functions. The previous syntax is still supported.
typedef F = List<T> Function<T>(T);
For more details see https://github.com/dart-lang/sdk/blob/master/docs/language/informal/generic-function-type-alias.md
Function types can also be specified inline
void foo<T, S>(T Function(int, S) aFunction) {...}
See also https://www.dartlang.org/guides/language/language-tour#typedefs
typedef LoggerOutputFunction = void Function(String msg);
this looks much more clear than previous version
Just slightly modified answer, according to the latest typedef syntax, The example could be updated to:
typedef LoggerOutputFunction = void Function(String msg);
class Logger {
LoggerOutputFunction out;
Logger() {
out = print;
}
void log(String msg) {
out(msg);
}
}
void timestampLoggerOutputFunction(String msg) {
String timeStamp = new Date.now().toString();
print('${timeStamp}: $msg');
}
void main() {
Logger l = new Logger();
l.log('Hello World');
l.out = timestampLoggerOutputFunction;
l.log('Hello World');
}
Typedef in Dart is used to create a user-defined function (alias) for other application functions,
Syntax: typedef function_name (parameters);
With the help of a typedef, we can also assign a variable to a function.
Syntax:typedef variable_name = function_name;
After assigning the variable, if we have to invoke it then we go as:
Syntax: variable_name(parameters);
Example:
// Defining alias name
typedef MainFunction(int a, int b);
functionOne(int a, int b) {
print("This is FunctionOne");
print("$a and $b are lucky numbers !!");
}
functionTwo(int a, int b) {
print("This is FunctionTwo");
print("$a + $b is equal to ${a + b}.");
}
// Main Function
void main() {
// use alias
MainFunction number = functionOne;
number(1, 2);
number = functionTwo;
// Calling number
number(3, 4);
}
Output:
This is FunctionOne
1 and 2 are lucky numbers !!
This is FunctionTwo
3 + 4 is equal to 7
Since dart version 2.13 you can use typedef not only with functions but with every object you want.
Eg this code is now perfectly valid:
typedef IntList = List<int>;
IntList il = [1, 2, 3];
For more details see updated info:
https://dart.dev/guides/language/language-tour#typedefs
https://www.tutorialspoint.com/dart_programming/dart_programming_typedef.htm
typedef ManyOperation(int firstNo , int secondNo); //function signature
Add(int firstNo,int second){
print("Add result is ${firstNo+second}");
}
Subtract(int firstNo,int second){
print("Subtract result is ${firstNo-second}");
}
Divide(int firstNo,int second){
print("Divide result is ${firstNo/second}");
}
Calculator(int a,int b ,ManyOperation oper){
print("Inside calculator");
oper(a,b);
}
main(){
Calculator(5,5,Add);
Calculator(5,5,Subtract);
Calculator(5,5,Divide);
}

Question about var type

I am new to C# 3.0 var type. Here I have a question about this type. Take the following simple codes in a library as example:
public class MyClass {
public var Fn(var inValue)
{
if ( inValue < 0 )
{
return 1.0;
}
else
{
return inValue;
}
}
}
I think the parameter is an anonymous type. If I pass in a float value, then the Fn should return a float type. If a double value type is passed in, will the Fn return a double type? How about an integer value type as input value?
Actually, I would like to use var type with this function/method to get different return types with various input types dynamically. I am not sure if this usage is correct or not?
You can't use var for return values or parameter types (or fields). You can only use it for local variables.
Eric Lippert has a blog post about why you can't use it for fields. I'm not sure if there's a similar one for return values and parameter types. Parameter types certainly doesn't make much sense - where could the compiler infer the type from? Just what methods you try to call on the parameters? (Actually that's pretty much what F# does, but C# is more conservative.)
Don't forget that var is strictly static typing - it's just a way of getting the compiler to infer the static type for you. It's still just a single type, exactly as if you'd typed the name into the code. (Except of course with anonymous types you can't do that, which is one motivation for the feature.)
EDIT: For more details on var, you can download chapter 8 of C# in Depth for free at Manning's site - this includes the section on var. Obviously I hope you'll then want to buy the book, but there's no pressure :)
EDIT: To address your actual aim, you can very nearly implement all of this with a generic method:
public class MyClass
{
public T Fn<T>(T inValue) where T : struct
{
Comparer<T> comparer = Comparer<T>.Default;
T zero = default(T);
if (comparer.Compare(inValue, zero) < 0)
{
// This is the tricky bit.
return 1.0;
}
else
{
return inValue;
}
}
}
As shown in the listing, the tricky bit is working out what "1" means for an arbitrary type. You could hard code a set of values, but it's a bit ugly:
public class MyClass
{
private static readonly Dictionary<Type, object> OneValues
= new Dictionary<Type, object>
{
{ typeof(int), 1 },
{ typeof(long), 1L },
{ typeof(double), 1.0d },
{ typeof(float), 1.0f },
{ typeof(decimal), 1m },
};
public static T Fn<T>(T inValue) where T : struct
{
Comparer<T> comparer = Comparer<T>.Default;
T zero = default(T);
if (comparer.Compare(inValue, zero) < 0)
{
object one;
if (!OneValues.TryGetValue(typeof(T), out one))
{
// Not sure of the best exception to use here
throw new ArgumentException
("Unable to find appropriate 'one' value");
}
return (T) one;
}
else
{
return inValue;
}
}
}
Icky - but it'll work. Then you can write:
double x = MyClass.Fn(3.5d);
float y = MyClass.Fn(3.5f);
int z = MyClass.Fn(2);
etc
You cannot use var as a return type for a method.